diff --git a/apps/flame-defi/app/bridge/page.tsx b/apps/flame-defi/app/bridge/page.tsx index 2ed787c..0aca51f 100644 --- a/apps/flame-defi/app/bridge/page.tsx +++ b/apps/flame-defi/app/bridge/page.tsx @@ -46,7 +46,7 @@ export default function BridgePage(): React.ReactElement {
-
+
    {tabs.map((tab) => ( (""); const [isRecipientAddressEditable, setIsRecipientAddressEditable] = useState(false); + const handleEditRecipientClick = useCallback(() => { setIsRecipientAddressEditable(!isRecipientAddressEditable); }, [isRecipientAddressEditable]); + const handleEditRecipientSave = () => { setIsRecipientAddressEditable(false); // reset evmWalletState when user manually enters address resetEvmWalletState(); }; + const handleEditRecipientClear = () => { setIsRecipientAddressEditable(false); setRecipientAddressOverride(""); @@ -166,6 +169,7 @@ export default function DepositCard(): React.ReactElement { }, [selectedEvmChain, handleConnectEvmWallet]); const handleDeposit = async () => { + console.log("handleDeposit"); if (!selectedCosmosChain || !selectedIbcCurrency) { addNotification({ toastOpts: { @@ -359,7 +363,7 @@ export default function DepositCard(): React.ReactElement { {isAnimating ? ( ) : ( -
    +
    @@ -515,7 +519,7 @@ export default function DepositCard(): React.ReactElement {
    )} - {!isBridgePage && (
    {userAccount.address ? ( -
    +
    diff --git a/apps/flame-defi/app/components/NetworkSelector/NetworkSelector.tsx b/apps/flame-defi/app/components/NetworkSelector/NetworkSelector.tsx index 97dfbd5..b61292a 100644 --- a/apps/flame-defi/app/components/NetworkSelector/NetworkSelector.tsx +++ b/apps/flame-defi/app/components/NetworkSelector/NetworkSelector.tsx @@ -25,6 +25,11 @@ export default function NetworkSelector(): React.ReactElement { [selectFlameNetwork], ); + //NOTES: THING TO TRACK: + // evmChainOptions + // selectedEvmChain + // selectedEvmNetwork + return ( + handleInputChange(Number(e.target.value), true) + } + className="normalize-input w-[100%]" + placeholder="0" + /> + $0 +
    +
    +
    + {tokenOne?.Icon && } + {tokenOne?.symbol} +
    +
    + {/* TODO: This will be replaced with the wallet balance */} + {"0"} + {tokenOne?.symbol} + + Max + +
    +
    +
    +
    +
    null} + className={`flex flex-col rounded-md p-transition bg-semi-white border border-solid border-transparent hover:border-grey-medium mt-2 p-4`} + > +
    +
    + + handleInputChange(Number(e.target.value), false) + } + className="normalize-input w-[100%]" + placeholder="0" + /> + $0 +
    +
    +
    + {tokenTwo?.Icon && } + {tokenTwo?.symbol} +
    +
    + {/* TODO: This will be replaced with the wallet balance */} + {"0"} + {tokenTwo?.symbol} + + Max + +
    +
    +
    +
    + {/* TODO: This is a temp example of how we might conditionally render the action button */} + {actionText !== "Deposit" && ( +
    + {actionText} +
    + )} + {/* TODO: This is a temp example of how we might conditionally render the action button */} + {actionText === "Deposit" && ( + console.log("DO A DEPOSIT")} + buttonText="Deposit" + className="w-full mt-5" + /> + )} +
    + )} +
    + ); +} diff --git a/apps/flame-defi/app/pool/components/MiniAreaChart.tsx b/apps/flame-defi/app/pool/components/MiniAreaChart.tsx new file mode 100644 index 0000000..5cefe7e --- /dev/null +++ b/apps/flame-defi/app/pool/components/MiniAreaChart.tsx @@ -0,0 +1,108 @@ +// ChartExample.tsx +import React from "react"; +import ReactEChartsCore from "echarts-for-react/lib/core"; +import * as echarts from "echarts/core"; +import { + LineChart, + LineSeriesOption, + ScatterChart, + ScatterSeriesOption, +} from "echarts/charts"; +import { GridComponent, GridComponentOption } from "echarts/components"; +import { CanvasRenderer } from "echarts/renderers"; + +// Register only the chart types and components we use +echarts.use([LineChart, ScatterChart, GridComponent, CanvasRenderer]); + +// Type for ECharts option +type ECOption = echarts.ComposeOption< + LineSeriesOption | ScatterSeriesOption | GridComponentOption +>; + +const MiniAreaChart: React.FC = () => { + // Sample data (use your real data here) + const data: number[] = [ + 20, 18, 19, 17, 18, 16, 14, 15, 14, 16, 15, 18, 20, 22, 21, 23, + ]; + + // The last data point + const lastValue = data[data.length - 1]; + + const option: ECOption = { + // Remove all labels, axis lines, ticks, etc. + xAxis: { + type: "category", + data: data.map((_, i) => i.toString()), + show: false, + }, + yAxis: { + type: "value", + show: false, + // Add min and max to control the vertical positioning + min: (value: { min: number; max: number }) => + value.min - (value.max - value.min) * 0.2, + max: (value: { min: number; max: number }) => + value.max + (value.max - value.min) * 0.2, + }, + grid: { + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + tooltip: { + show: false, // disable hover tooltip + }, + series: [ + // Main line + { + type: "line", + data, + smooth: false, + showSymbol: false, + lineStyle: { + color: "rgba(230, 149, 41, 1)", // green line (adjust as needed) + width: 2, + }, + // We'll use a markLine for the dotted baseline + markLine: { + symbol: ["none", "none"], + lineStyle: { + type: "dotted", + color: "rgba(230, 149, 41, 1)", + width: 1, + }, + silent: true, + symbolSize: [0, 0], + label: { + show: false, + }, + data: [{ yAxis: lastValue }], + }, + }, + // Dot (circle) on the last data point + { + type: "scatter", + data: [[data.length - 1, lastValue]], + symbolSize: 8, + itemStyle: { + color: "rgba(230, 149, 41, 1)", + }, + // No label or additional hover + emphasis: { disabled: true }, + }, + ], + }; + + return ( +
    + +
    + ); +}; + +export default MiniAreaChart; diff --git a/apps/flame-defi/app/pool/components/NewPoolPosition.tsx b/apps/flame-defi/app/pool/components/NewPoolPosition.tsx new file mode 100644 index 0000000..805e70c --- /dev/null +++ b/apps/flame-defi/app/pool/components/NewPoolPosition.tsx @@ -0,0 +1,137 @@ +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, + Button, +} from "@repo/ui/shadcn-primitives"; +import { useState } from "react"; +import TokenPairsStep from "./TokenPairsStep"; +import PriceRangeStep from "./PriceRangeStep"; +import DepositAmountsStep from "./DepositAmountsStep"; +import { feeData, tokens } from "../../constants"; +import { TokenItem } from "@repo/ui/types"; +import { ChevronDownIcon, ResetIcon } from "@repo/ui/icons"; +import { useAccount } from "wagmi"; + +export interface StepProps { + step: number; + setStep: (thing: number) => void; + tokenPair: TokenPair; + selectedFeeTier: FeeData | undefined; +} + +export interface TokenPair { + tokenOne: TokenItem | undefined; + tokenTwo: TokenItem | undefined; +} + +export interface FeeData { + id: number; + feePercent: string; + text: string; + tvl: string; + selectPercent: string; +} + +export default function NewPoolPosition({ + newPositionPage, + setNewPositionPage, +}: { + newPositionPage: boolean; + setNewPositionPage: (newPositionPage: boolean) => void; +}): React.ReactElement { + const userAccount = useAccount(); + const [step, setStep] = useState(0); + const [selectedFeeTier, setSelectedFeeTier] = useState( + feeData[0], + ); + const [tokenPair, setTokenPair] = useState({ + tokenOne: tokens[0], + tokenTwo: undefined, + }); + + const reset = () => { + setStep(0); + setTokenPair({ + tokenOne: tokens[0], + tokenTwo: undefined, + }); + setSelectedFeeTier(feeData[0]); + }; + + return ( +
    +
    + {userAccount.address && newPositionPage && ( +
    setNewPositionPage(false)} + > + +

    Your Positions

    +
    + )} +
    +
    + + + + + Token Pairs/Fees + + + + + + Price Range + + + + + + Deposit Amounts + + + + + +
    +
    + + + +
    +
    + ); +} diff --git a/apps/flame-defi/app/pool/components/PriceRangeStep.tsx b/apps/flame-defi/app/pool/components/PriceRangeStep.tsx new file mode 100644 index 0000000..37e44ae --- /dev/null +++ b/apps/flame-defi/app/pool/components/PriceRangeStep.tsx @@ -0,0 +1,206 @@ +"use client"; + +import { StepProps } from "./NewPoolPosition"; +import { EditIcon, MinusIcon, PlusIcon } from "@repo/ui/icons"; +import { ActionButton, ToggleSwitch } from "@repo/ui/components"; +import { useCallback, useEffect, useState } from "react"; +import AreaChartWithRange from "./AreaChartWithRange"; +import { Button } from "@repo/ui/shadcn-primitives"; +import MiniAreaChart from "./MiniAreaChart"; + +export default function PriceRangeStep({ + step, + setStep, + tokenPair, +}: StepProps): React.ReactElement { + const { tokenOne, tokenTwo } = tokenPair; + const [selectedToken, setSelectedToken] = useState(tokenOne?.symbol || ""); + const [selectedRange, setSelectedRange] = useState("Full Range"); + const [minPrice, setMinPrice] = useState(0); + const [maxPrice, setMaxPrice] = useState(Infinity); + + useEffect(() => { + if (step === 0) { + setSelectedToken(tokenOne?.symbol || ""); + setSelectedRange("Full Range"); + setMinPrice(0); + setMaxPrice(Infinity); + } + }, [step, tokenOne]); + + useEffect(() => { + if (selectedRange === "Full Range") { + setMinPrice(0); + setMaxPrice(Infinity); + } else { + setMinPrice(0.001); + setMaxPrice(4); + } + }, [selectedRange]); + + const handleMinPriceChange = useCallback( + (action: "increase" | "decrease") => { + if (action === "increase") { + setMinPrice(minPrice + 0.01); + } else { + const newPrice = minPrice - 0.01; + if (newPrice >= 0) { + setMinPrice(newPrice); + } + } + }, + [minPrice], + ); + + const handleMaxPriceChange = useCallback( + (action: "increase" | "decrease") => { + if (maxPrice === Infinity) { + setMaxPrice(0); + } else if (action === "increase") { + setMaxPrice(maxPrice + 0.01); + } else { + const newPrice = maxPrice - 0.01; + if (newPrice >= 0) { + setMaxPrice(newPrice); + } + } + }, + [maxPrice], + ); + + return ( +
    + {step > 1 && ( +
    +
    +
    + +
    +
    +
    + {selectedRange} +
    + +
    +
    +
    + )} + {step === 1 && ( +
    +
    +

    Set price range

    +
    + +
    +
    +
    + +
    +

    + {selectedRange === "Full Range" + ? "Providing full range liquidity ensures continuous market participation across all possible prices, offering simplicity but with potential for higher impermanent loss." + : "Custom range allows you to concentrate your liquidity within specific price bounds, enhancing capital efficiency and fee earnings but requiring more active management."} +

    +
    + +
    +
    +
    +
    + + Min Price + + setMinPrice(Number(e.target.value))} + /> + + {selectedToken === tokenOne?.symbol + ? tokenTwo?.symbol + : tokenOne?.symbol}{" "} + per {selectedToken} + +
    +
    +
    handleMinPriceChange("increase")} + > + +
    +
    handleMinPriceChange("decrease")} + > + +
    +
    +
    +
    +
    + + Max Price + + setMaxPrice(Number(e.target.value))} + /> + + {selectedToken === tokenOne?.symbol + ? tokenTwo?.symbol + : tokenOne?.symbol}{" "} + per {selectedToken} + +
    +
    +
    handleMaxPriceChange("increase")} + > + +
    +
    handleMaxPriceChange("decrease")} + > + +
    +
    +
    +
    + setStep(2)} + /> +
    + )} +
    + ); +} diff --git a/apps/flame-defi/app/pool/components/TokenPairsStep.tsx b/apps/flame-defi/app/pool/components/TokenPairsStep.tsx new file mode 100644 index 0000000..9bc44a7 --- /dev/null +++ b/apps/flame-defi/app/pool/components/TokenPairsStep.tsx @@ -0,0 +1,195 @@ +import { ActionButton, TokenSelector } from "@repo/ui/components"; +import { Button, DialogTrigger } from "@repo/ui/shadcn-primitives"; +import { TokenItem } from "@repo/ui/types"; +import { tokens, feeData } from "../../constants"; +import { useState } from "react"; +import { CheckMarkIcon, ChevronDownIcon, EditIcon } from "@repo/ui/icons"; +import { FeeData, TokenPair } from "./NewPoolPosition"; + +export interface TokenPairsStepProps { + step: number; + setStep: (thing: number) => void; + setTokenPair: (thing: TokenPair) => void; + tokenPair: TokenPair; + selectedFeeTier: FeeData | undefined; + setSelectedFeeTier: (thing: FeeData) => void; +} + +const CustomTokenButton = ({ + selectedToken, + defaultTitle, +}: { + selectedToken?: TokenItem | null; + defaultTitle: string; +}) => ( + +
    +
    + {selectedToken?.Icon && } +

    + {selectedToken?.symbol || defaultTitle} +

    +
    + +
    +
    +); + +export default function TokenPairsStep({ + step, + setStep, + setTokenPair, + tokenPair, + selectedFeeTier, + setSelectedFeeTier, +}: TokenPairsStepProps): React.ReactElement { + const [showMore, setShowMore] = useState(false); + const { tokenOne, tokenTwo } = tokenPair; + const setToken = ( + position: "tokenOne" | "tokenTwo", + token: TokenItem | undefined, + ) => { + setTokenPair({ + ...tokenPair, + [position]: token, + }); + }; + + return ( +
    + {step > 0 && ( +
    +
    +
    + {tokenOne?.Icon && } + {tokenTwo?.Icon && } +

    + {tokenOne?.symbol} / {tokenTwo?.symbol} +

    + + Fees: {selectedFeeTier?.feePercent} + +
    + +
    +
    + )} + {step === 0 && ( +
    +
    +

    Select pair

    +

    + Choose the tokens you want to provide liquidity for. +

    +
    + setToken("tokenOne", token)} + CustomTokenButton={CustomTokenButton} + /> + setToken("tokenTwo", token)} + CustomTokenButton={CustomTokenButton} + /> +
    +
    +
    +
    +

    Fee tier

    +

    + The amount earned providing liquidity. Choose an amount that + suits your risk tolerance and strategy. +

    +
    +
    +
    + + {selectedFeeTier?.feePercent} fee tier + {selectedFeeTier?.id === 0 && ( + + Recommended + + )} + + + {selectedFeeTier?.text} + +
    +
    + +
    +
    +
    + {feeData.map(({ feePercent, text, tvl, selectPercent }, i) => ( +
    feeData[i] && setSelectedFeeTier(feeData[i])} + > +
    + + {feePercent} + {selectedFeeTier?.id === i && ( + + )} + + {text} +
    +
    + {tvl} + + {selectPercent} + +
    +
    + ))} +
    + setStep(1)} + disabled={ + tokenPair.tokenOne === undefined || + tokenPair.tokenTwo === undefined + } + /> +
    +
    + )} +
    + ); +} diff --git a/apps/flame-defi/app/pool/page.tsx b/apps/flame-defi/app/pool/page.tsx index d832a5f..3c6c42c 100644 --- a/apps/flame-defi/app/pool/page.tsx +++ b/apps/flame-defi/app/pool/page.tsx @@ -1,28 +1,62 @@ +"use client"; + import { ActionButton } from "@repo/ui/components"; import { InboxIcon, PlusIcon } from "@repo/ui/icons"; +import { useEvmWallet } from "features/EvmWallet/hooks/useEvmWallet"; import type React from "react"; +import { useAccount } from "wagmi"; +import NewPoolPosition from "./components/NewPoolPosition"; +import { useState } from "react"; export default function PoolPage(): React.ReactElement { + const { connectEvmWallet } = useEvmWallet(); + // TODO: this is a temporary state to display the new position page + const [newPositionPage, setNewPositionPage] = useState(false); + const userAccount = useAccount(); + + // TODO: Actually think through how the your positions, connect and new position pages should be displayed + return (
    -
    -
    -

    Pools

    - -
    -
    -
    - -

    - Your active V3 liquidity positions will appear here. -

    - +
    + {userAccount.address && !newPositionPage && ( +
    + setNewPositionPage(true)} + buttonText="New Position" + className="mt-0" + PrefixIcon={PlusIcon} + /> +
    + )} + {userAccount.address && newPositionPage && ( + + )} + {!newPositionPage && ( +
    +

    + {newPositionPage ? "Create Position" : "Pools"} +

    +
    +
    + +

    + Your active V3 liquidity positions will appear here. +

    + {!userAccount.address && ( + connectEvmWallet()} + /> + )} +
    +
    -
    + )}
    ); diff --git a/apps/flame-defi/app/pool/useDepositTxn.tsx b/apps/flame-defi/app/pool/useDepositTxn.tsx new file mode 100644 index 0000000..8dc0e3b --- /dev/null +++ b/apps/flame-defi/app/pool/useDepositTxn.tsx @@ -0,0 +1,13 @@ +import { TokenState } from "@repo/ui/types"; + +export function useDepositTxn(inputOne: TokenState, inputTwo: TokenState) { + // TODO: pull in real token values and balances from api and calculate the txn info here + + if (inputOne.value === undefined || inputTwo.value === undefined) { + return "Enter an amount"; + } else if (inputOne.value === 0 || inputTwo.value === 0) { + return "Amount must be greater than 0"; + } else { + return "Deposit"; + } +} diff --git a/apps/flame-defi/app/swap/page.tsx b/apps/flame-defi/app/swap/page.tsx index 913749d..e8fb5d4 100644 --- a/apps/flame-defi/app/swap/page.tsx +++ b/apps/flame-defi/app/swap/page.tsx @@ -7,24 +7,14 @@ import { TokenSelector, SettingsPopover, } from "@repo/ui/components"; -import type { TokenItem } from "./useTokenModal"; -import { useTokenModal } from "./useTokenModal"; import { useState } from "react"; import { useAccount } from "wagmi"; import { useEvmWallet } from "features/EvmWallet"; import { useTxnInfo } from "./useTxnInfo"; -enum TOKEN_INPUTS { - TOKEN_ONE = "token_one", - TOKEN_TWO = "token_two", -} - -export interface TokenState { - token?: TokenItem | null; - value: number | undefined; -} +import { tokens, TOKEN_INPUTS } from "../constants"; +import { TokenState } from "@repo/ui/types"; export default function SwapPage(): React.ReactElement { - const { tokens } = useTokenModal(); const { connectEvmWallet } = useEvmWallet(); const userAccount = useAccount(); const [inputSelected, setInputSelected] = useState(TOKEN_INPUTS.TOKEN_ONE); @@ -59,29 +49,30 @@ export default function SwapPage(): React.ReactElement { return (
    -
    +
    -

    Swap

    +

    Swap

    null} onClick={() => setInputSelected(TOKEN_INPUTS.TOKEN_ONE)} - className={`flex flex-col rounded-md p-2 transition border border-solid border-transparent hover:border-grey-light ${ + className={`flex flex-col rounded-md p-4 transition border border-solid border-transparent hover:border-grey-medium ${ inputSelected === TOKEN_INPUTS.TOKEN_ONE ? "bg-background border-grey-medium" - : "bg-white/[0.04]" + : "bg-semi-white" }`} > +
    Sell
    handleInputChange(Number(e.target.value), true)} - className="w-[45%] sm:max-w-[62%] flex-1 bg-transparent focus:outline-none text-[36px] placeholder:text-grey-light [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + className="normalize-input w-[45%] sm:max-w-[62%]" placeholder="0" /> -
    +
    ({ ...prev, token })) } /> + {inputOne.token ? ( +
    + {inputOne.value ? inputOne.value : "0"} + {inputOne.token?.symbol} + + Max + +
    + ) : ( +
    + )}
    - $100 + $0
    null} onClick={() => setInputSelected(TOKEN_INPUTS.TOKEN_TWO)} - className={`flex flex-col rounded-md p-2 transition border border-solid border-transparent hover:border-grey-light ${ + className={`flex flex-col rounded-md p-4 transition border border-solid border-transparent hover:border-grey-medium ${ inputSelected === TOKEN_INPUTS.TOKEN_TWO ? "bg-background border-grey-medium" - : "bg-white/[0.04]" + : "bg-semi-white" }`} > +
    Buy
    handleInputChange(Number(e.target.value), false)} - className="w-[45%] sm:max-w-[62%] flex-1 bg-transparent focus:outline-none text-[36px] placeholder:text-grey-light [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + className="normalize-input w-[45%] sm:max-w-[62%]" placeholder="0" /> -
    +
    ({ ...prev, token })) } /> +
    - $100 + $0
    {!userAccount.address && ( @@ -147,7 +151,7 @@ export default function SwapPage(): React.ReactElement { )} {/* TODO: This is a temp example of how we might conditionally render the action button */} {userAccount.address && actionText !== "Swap" && ( -
    +
    {actionText}
    )} diff --git a/apps/flame-defi/app/swap/useTokenModal.tsx b/apps/flame-defi/app/swap/useTokenModal.tsx deleted file mode 100644 index 396c3ef..0000000 --- a/apps/flame-defi/app/swap/useTokenModal.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { - CelestiaIcon, - MilkTiaIcon, - StrideTiaIcon, - UsdcIcon, - WrappedTiaIcon, -} from "@repo/ui/icons"; -import { IconProps } from "@repo/ui/types"; - -export interface TokenItem { - Icon: React.ComponentType; - title: string; - symbol: string; -} - -// NOTE: temporary tokens until we have a real token list from a api -const tokens: TokenItem[] = [ - { - Icon: CelestiaIcon, - title: "TIA", - symbol: "TIA", - }, - { - Icon: WrappedTiaIcon, - title: "Wrapped Celestia", - symbol: "WTIA", - }, - { - Icon: MilkTiaIcon, - title: "Milk TIA", - symbol: "milkTIA", - }, - { - Icon: StrideTiaIcon, - title: "Stride TIA", - symbol: "stTIA", - }, - { - Icon: UsdcIcon, - title: "USDC", - symbol: "USDC", - }, -]; - -export function useTokenModal() { - return { - tokens, - }; -} diff --git a/apps/flame-defi/app/swap/useTxnInfo.tsx b/apps/flame-defi/app/swap/useTxnInfo.tsx index 66f1ef7..d5a5c20 100644 --- a/apps/flame-defi/app/swap/useTxnInfo.tsx +++ b/apps/flame-defi/app/swap/useTxnInfo.tsx @@ -1,4 +1,4 @@ -import { TokenState } from "./page"; +import { TokenState } from "@repo/ui/types"; export function useTxnInfo(inputOne: TokenState, inputTwo: TokenState) { // TODO: pull in real token values and balances from api and calculate the txn info here diff --git a/apps/flame-defi/package.json b/apps/flame-defi/package.json index 03f7712..d01e090 100644 --- a/apps/flame-defi/package.json +++ b/apps/flame-defi/package.json @@ -24,6 +24,8 @@ "@repo/ui": "*", "@tanstack/react-query": "^5.61.0", "chain-registry": "^1.69.45", + "echarts": "^5.6.0", + "echarts-for-react": "^3.0.2", "ethers": "^6.13.2", "next": "^15.1.0", "osmojs": "^16.15.0", diff --git a/apps/flame-defi/tailwind.config.js b/apps/flame-defi/tailwind.config.js index f9f31c8..2e32849 100644 --- a/apps/flame-defi/tailwind.config.js +++ b/apps/flame-defi/tailwind.config.js @@ -15,6 +15,7 @@ export default { colors: { white: 'hsl(var(--color-white))', whitest: 'hsl(var(--color-whitest))', + 'semi-white': 'hsl(var(--color-semi-white))', 'grey-dark': 'hsl(var(--color-grey-dark))', 'grey-medium': 'hsl(var(--color-grey-medium))', 'grey-light': 'hsl(var(--color-grey-light))', diff --git a/package-lock.json b/package-lock.json index 4ffc25f..6d69672 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "apps/*", "packages/*" ], + "dependencies": { + "eslint-plugin-react-hooks": "^5.1.0" + }, "devDependencies": { "prettier": "^3.4.2", "turbo": "^2.3.3", @@ -33,6 +36,8 @@ "@repo/ui": "*", "@tanstack/react-query": "^5.61.0", "chain-registry": "^1.69.45", + "echarts": "^5.6.0", + "echarts-for-react": "^3.0.2", "ethers": "^6.13.2", "next": "^15.1.0", "osmojs": "^16.15.0", @@ -1621,7 +1626,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", - "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -1639,7 +1643,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1651,7 +1654,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -1660,7 +1662,6 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", - "dev": true, "dependencies": { "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", @@ -1674,7 +1675,6 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -1686,7 +1686,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", - "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1708,14 +1707,12 @@ "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, "engines": { "node": ">=18" }, @@ -1727,7 +1724,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -1739,7 +1735,6 @@ "version": "9.18.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", - "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -1748,7 +1743,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", - "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -1757,7 +1751,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", - "dev": true, "dependencies": { "@eslint/core": "^0.10.0", "levn": "^0.4.1" @@ -2036,7 +2029,6 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, "engines": { "node": ">=18.18.0" } @@ -2045,7 +2037,6 @@ "version": "0.16.6", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" @@ -2058,7 +2049,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, "engines": { "node": ">=18.18" }, @@ -2071,7 +2061,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "engines": { "node": ">=12.22" }, @@ -2084,7 +2073,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", - "dev": true, "engines": { "node": ">=18.18" }, @@ -7005,8 +6993,7 @@ "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "node_modules/@types/glob": { "version": "7.2.0", @@ -7103,8 +7090,7 @@ "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/long": { "version": "4.0.2", @@ -8169,7 +8155,6 @@ "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -8191,7 +8176,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -8242,7 +8226,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -8869,7 +8852,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9050,7 +9032,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -9150,7 +9131,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -9444,8 +9424,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/consola": { "version": "3.4.0", @@ -9811,8 +9790,7 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deep-object-diff": { "version": "1.1.9", @@ -10093,6 +10071,36 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "node_modules/echarts": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, + "node_modules/echarts-for-react": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz", + "integrity": "sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "size-sensor": "^1.0.1" + }, + "peerDependencies": { + "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0", + "react": "^15.0.0 || >=16.0.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/eciesjs": { "version": "0.4.13", "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.13.tgz", @@ -10457,7 +10465,6 @@ "version": "9.18.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -10565,6 +10572,18 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -10607,7 +10626,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -10623,7 +10641,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10635,7 +10652,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -10647,7 +10663,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -10663,7 +10678,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -10678,7 +10692,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -10693,7 +10706,6 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "dev": true, "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", @@ -10722,7 +10734,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -10734,7 +10745,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -10746,7 +10756,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10755,7 +10764,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -11187,14 +11195,12 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fast-redact": { "version": "3.5.0", @@ -11276,7 +11282,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -11328,7 +11333,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -11340,8 +11344,7 @@ "node_modules/flatted": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", - "dev": true + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==" }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -11784,7 +11787,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -11992,7 +11994,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "engines": { "node": ">= 4" } @@ -12011,7 +12012,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -12027,7 +12027,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -12055,7 +12054,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -13862,8 +13860,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -13936,14 +13933,12 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -14014,7 +14009,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -14046,7 +14040,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -14155,8 +14148,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/log-symbols": { "version": "3.0.0", @@ -14455,7 +14447,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14589,8 +14580,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/neo-async": { "version": "2.6.2", @@ -15068,7 +15058,6 @@ "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -15297,7 +15286,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -15443,7 +15431,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -15811,7 +15798,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -16028,7 +16014,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -17120,6 +17105,12 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "node_modules/size-sensor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.2.tgz", + "integrity": "sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==", + "license": "ISC" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -17592,7 +17583,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -17696,7 +17686,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -18150,7 +18139,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -18543,7 +18531,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -19079,7 +19066,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -19264,7 +19250,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -19272,6 +19257,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zrender": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/zustand": { "version": "4.5.6", "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz", @@ -19325,17 +19325,6 @@ "fast-glob": "3.3.1" } }, - "packages/eslint-config/node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, "packages/eslint-config/node_modules/fast-glob": { "version": "3.3.1", "dev": true, diff --git a/package.json b/package.json index 66429aa..05e28db 100644 --- a/package.json +++ b/package.json @@ -21,5 +21,8 @@ "workspaces": [ "apps/*", "packages/*" - ] + ], + "dependencies": { + "eslint-plugin-react-hooks": "^5.1.0" + } } diff --git a/packages/ui/src/components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer.tsx b/packages/ui/src/components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer.tsx index d554eab..fc7c421 100644 --- a/packages/ui/src/components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer.tsx +++ b/packages/ui/src/components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer.tsx @@ -8,7 +8,7 @@ export const AnimatedArrowSpacer = ({ {[100, 80, 60, 40, 20, 10, 5, 1].map((width, index) => (
    [] = [ - { label: "Option 1", value: "option1" }, - { label: "Option 2", value: "option2" }, - { label: "Option 3", value: "option3" }, -]; +import { Dropdown } from "./Dropdown"; // Adjust the import path as needed describe("Dropdown Component", () => { test("renders with placeholder text", () => { diff --git a/packages/ui/src/components/Dropdown/Dropdown.tsx b/packages/ui/src/components/Dropdown/Dropdown.tsx index 807cce8..71806b1 100644 --- a/packages/ui/src/components/Dropdown/Dropdown.tsx +++ b/packages/ui/src/components/Dropdown/Dropdown.tsx @@ -148,11 +148,11 @@ export const Dropdown = ({ type="button" key={option.label} className={`w-full text-left ${ - selectedOption?.value === option.value ? "bg-white/5" : "" + selectedOption?.value === option.value ? "bg-semi-white" : "" }`} onClick={() => handleSelect(option)} > - + {option.LeftIcon && ( @@ -173,7 +173,7 @@ export const Dropdown = ({ setIsActive(false); }} > - + {option.LeftIcon && ( diff --git a/packages/ui/src/components/SettingsPopover/SettingsPopover.tsx b/packages/ui/src/components/SettingsPopover/SettingsPopover.tsx index 72ccd5b..26fc998 100644 --- a/packages/ui/src/components/SettingsPopover/SettingsPopover.tsx +++ b/packages/ui/src/components/SettingsPopover/SettingsPopover.tsx @@ -18,9 +18,7 @@ import { GearIcon } from "@repo/ui/icons"; import { InfoTooltip } from "../InfoTooltip/InfoTooltip"; import { useState } from "react"; -interface SettingsPopoverProps {} - -export const SettingsPopover: React.FC = () => { +export const SettingsPopover: React.FC = () => { const [customSlippage, setCustomSlippage] = useState(""); const [expertMode, setExpertMode] = useState(false); const [showExpertModeDialog, setShowExpertModeDialog] = useState(false); diff --git a/packages/ui/src/components/SideTag/SideTag.tsx b/packages/ui/src/components/SideTag/SideTag.tsx deleted file mode 100644 index 75f3050..0000000 --- a/packages/ui/src/components/SideTag/SideTag.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { UpRightSquareIcon } from "../../icons"; - -interface SideTagProps { - label: string; - url: string; -} - -/** - * SideTag component to render a side tag with an icon and label. - * @param label - * @param url - * @param iconClass - */ -export const SideTag = ({ label, url }: SideTagProps) => { - return ( - - ); -}; diff --git a/packages/ui/src/components/ToggleSwitch/ToggleSwitch.tsx b/packages/ui/src/components/ToggleSwitch/ToggleSwitch.tsx new file mode 100644 index 0000000..fafe6f3 --- /dev/null +++ b/packages/ui/src/components/ToggleSwitch/ToggleSwitch.tsx @@ -0,0 +1,42 @@ +interface ToggleSwitchProps { + toggleOptions: string[]; + className?: string; + selectedOption: string; + setSelectedOption: (option: string) => void; +} + +export function ToggleSwitch({ + toggleOptions, + className, + selectedOption, + setSelectedOption, +}: ToggleSwitchProps) { + return ( +
    +
    + {toggleOptions.map((option, i) => ( +
    setSelectedOption(option)} + className={` + flex items-center justify-center + flex-1 py-2 px-4 + cursor-pointer relative + font-medium + ${selectedOption === option ? "text-white" : "text-grey-light"} + `} + > + {option} +
    + ))} +
    + ); +} diff --git a/packages/ui/src/components/TokenSelector/TokenSelector.tsx b/packages/ui/src/components/TokenSelector/TokenSelector.tsx index b812841..d450ec3 100644 --- a/packages/ui/src/components/TokenSelector/TokenSelector.tsx +++ b/packages/ui/src/components/TokenSelector/TokenSelector.tsx @@ -15,27 +15,26 @@ import { CloseIcon, SearchIcon, } from "../../icons"; -import { IconProps } from "../../types"; - -interface TokenItem { - Icon: React.ComponentType; - title: string; - symbol: string; -} +import { TokenItem } from "../../types"; interface TokenSelectorProps { tokens: TokenItem[]; defaultTitle?: string; setSelectedToken: (token: TokenItem) => void; selectedToken?: TokenItem | null; + CustomTokenButton?: (props: { + selectedToken?: TokenItem | null; + defaultTitle: string; + }) => React.ReactElement; } -export const TokenSelector: React.FC = ({ +export const TokenSelector = ({ tokens, defaultTitle = "Select token", selectedToken, setSelectedToken, -}: TokenSelectorProps) => { + CustomTokenButton, +}: TokenSelectorProps): React.ReactElement => { const [open, setOpen] = useState(false); const [filteredTokens, setFilteredTokens] = useState(tokens); const [searchQuery, setSearchQuery] = useState(""); @@ -58,15 +57,24 @@ export const TokenSelector: React.FC = ({ return ( - -
    - {selectedToken?.Icon && } -

    - {selectedToken?.symbol || defaultTitle} -

    - -
    -
    + {CustomTokenButton ? ( + + ) : ( + +
    + {selectedToken?.Icon && } +

    + {selectedToken?.symbol || defaultTitle} +

    + +
    +
    + )}
    @@ -88,7 +96,7 @@ export const TokenSelector: React.FC = ({
    handleSelectToken({ symbol, title, Icon })} key={symbol} - className={`flex items-center justify-between space-x-2 p-2 rounded-md hover:bg-white/[0.04] transition cursor-pointer ${selectedToken?.symbol === symbol ? "bg-white/[0.04]" : ""}`} + className={`flex items-center justify-between space-x-2 p-2 rounded-md hover:bg-semi-white transition cursor-pointer ${selectedToken?.symbol === symbol ? "bg-semi-white" : ""}`} >
    diff --git a/packages/ui/src/components/TxnInfo/TxnInfo.tsx b/packages/ui/src/components/TxnInfo/TxnInfo.tsx index 8e5cd95..27d897a 100644 --- a/packages/ui/src/components/TxnInfo/TxnInfo.tsx +++ b/packages/ui/src/components/TxnInfo/TxnInfo.tsx @@ -7,9 +7,7 @@ import { import { InfoTooltip } from "@repo/ui/components"; import { GasIcon } from "@repo/ui/icons"; -interface TxnInfoProps {} - -export const TxnInfo = ({}: TxnInfoProps) => { +export const TxnInfo = () => { // TODO: get the real calculated data return ( diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index f353faf..3d07c22 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -3,8 +3,9 @@ export * from "./CopyToClipboardButton/CopyToClipboardButton"; export * from "./Dropdown/Dropdown"; export * from "./AnimatedDownArrowSpacer/AnimatedDownArrowSpacer"; export * from "./Footer/Footer"; -export * from "./SideTag/SideTag"; +export * from "../../../../apps/flame-defi/app/components/SideTag/SideTag"; export * from "./TokenSelector/TokenSelector"; export * from "./SettingsPopover/SettingsPopover"; export * from "./InfoTooltip/InfoTooltip"; export * from "./TxnInfo/TxnInfo"; +export * from "./ToggleSwitch/ToggleSwitch"; diff --git a/packages/ui/src/icons/MinusIcon.tsx b/packages/ui/src/icons/MinusIcon.tsx new file mode 100644 index 0000000..3711932 --- /dev/null +++ b/packages/ui/src/icons/MinusIcon.tsx @@ -0,0 +1,22 @@ +import type { IconProps } from "../types"; + +export const MinusIcon: React.FC = ({ + className = "", + size = 24, +}: IconProps) => { + return ( + + ); +}; diff --git a/packages/ui/src/icons/ResetIcon.tsx b/packages/ui/src/icons/ResetIcon.tsx new file mode 100644 index 0000000..7d7dfcf --- /dev/null +++ b/packages/ui/src/icons/ResetIcon.tsx @@ -0,0 +1,26 @@ +import type { IconProps } from "../types"; + +export const ResetIcon: React.FC = ({ + className = "", + size = 24, +}: IconProps) => { + return ( + + ); +}; diff --git a/packages/ui/src/icons/index.ts b/packages/ui/src/icons/index.ts index 51509c4..da107fe 100644 --- a/packages/ui/src/icons/index.ts +++ b/packages/ui/src/icons/index.ts @@ -27,3 +27,5 @@ export * from "./ClipboardIcon"; export * from "./PowerIcon"; export * from "./SearchIcon"; export * from "./CheckMarkIcon"; +export * from "./MinusIcon"; +export * from "./ResetIcon"; diff --git a/packages/ui/src/shadcn-primitives/breadcrumbs.tsx b/packages/ui/src/shadcn-primitives/breadcrumbs.tsx new file mode 100644 index 0000000..9571b30 --- /dev/null +++ b/packages/ui/src/shadcn-primitives/breadcrumbs.tsx @@ -0,0 +1,114 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; +import { cn } from "../lib/utils"; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>