SolanaUISolanaUI

Trade Box

A perps/margin trading form with long/short toggle, token input, leverage slider, and order details

4,812.50
5x
Est. Entry Price$162.56
Liquidation Price$132.45
Fees0.05%
import { TradeBox } from "@/components/sol/trade-box";

const SOL_ICON =
  "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png";
const USDC_ICON =
  "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png";

export function TradeBoxDemo() {
  return (
    <TradeBox
      tokens={[
        { icon: USDC_ICON, symbol: "USDC" },
        { icon: SOL_ICON, symbol: "SOL" },
      ]}
      defaultToken="USDC"
      balance="4,812.50"
      details={[
        { label: "Est. Entry Price", value: "$162.56" },
        { label: "Liquidation Price", value: "$132.45", className: "text-red-400" },
        { label: "Fees", value: "0.05%" },
      ]}
    />
  );
}

Installation

pnpm dlx shadcn@latest add @solanaui/trade-box
npx shadcn@latest add @solanaui/trade-box
yarn dlx shadcn@latest add @solanaui/trade-box

Usage

TradeBox is purpose-built for perpetuals and margin trading. It always includes long/short toggle buttons and a leverage slider.

For non-trading actions like staking, lending, depositing, or bridging, use ActionBox instead.

<TradeBox
  tokens={[{ icon: USDC_ICON, symbol: "USDC" }]}
  defaultToken="USDC"
  balance="4,812.50"
  leverageMin={1}
  leverageMax={50}
  leverageDefault={5}
  details={[
    { label: "Est. Entry Price", value: "$162.56" },
    { label: "Liquidation Price", value: "$132.45", className: "text-red-400" },
    { label: "Fees", value: "0.05%" },
  ]}
  submitLabel="Open Long"
/>

Custom Labels

<TradeBox
  tokens={[{ icon: SOL_ICON, symbol: "SOL" }]}
  defaultToken="SOL"
  labels={["Buy", "Sell"]}
  defaultSide="long"
  leverageMax={20}
  submitLabel="Place Order"
/>

Submit Handler

Pass onSubmit to handle order execution when the button is clicked.

<TradeBox
  tokens={[{ icon: SOL_ICON, symbol: "SOL" }]}
  defaultToken="SOL"
  onSubmit={() => {
    // Execute trade logic
  }}
/>

Source Code

"use client";import { LeverageSlider } from "@/registry/sol/leverage-slider";import { TokenInput } from "@/registry/sol/token-input";import { TradeButtons } from "@/registry/sol/trade-buttons";import { Button } from "@/components/ui/button";import { Separator } from "@/components/ui/separator";import type { DetailRow } from "@/registry/lib/types";import { cn } from "@/lib/utils";type TradeBoxDetail = DetailRow;interface TradeBoxProps {  tokens: { icon: string; symbol: string }[];  defaultToken?: string;  balance?: string;  labels?: [string, string];  defaultSide?: string;  leverageMin?: number;  leverageMax?: number;  leverageDefault?: number;  leverageStep?: number;  details?: TradeBoxDetail[];  submitLabel?: string;  onSubmit?: () => void;  className?: string;}const TradeBox = ({  tokens,  defaultToken,  balance,  labels = ["Long", "Short"],  defaultSide = "long",  leverageMin = 1,  leverageMax = 50,  leverageDefault = 5,  leverageStep = 1,  details,  submitLabel = "Open Long",  onSubmit,  className,}: TradeBoxProps) => {  return (    <div className={cn("flex flex-col gap-4 border rounded-lg p-4", className)}>      <TradeButtons defaultValue={defaultSide} labels={labels} />      <Separator />      <div className="flex flex-col gap-2">        <TokenInput          tokens={tokens}          defaultToken={defaultToken}          balance={balance}        />      </div>      <LeverageSlider        min={leverageMin}        max={leverageMax}        defaultValue={[leverageDefault]}        step={leverageStep}      />      {details && details.length > 0 && (        <>          <Separator />          <div className="flex flex-col gap-1.5 text-sm">            {details.map((detail) => (              <div key={detail.label} className="flex justify-between">                <span className="text-muted-foreground">{detail.label}</span>                <span className={detail.className}>{detail.value}</span>              </div>            ))}          </div>        </>      )}      <Button className="w-full" size="lg" onClick={onSubmit}>        {submitLabel}      </Button>    </div>  );};export type { TradeBoxProps, TradeBoxDetail };export { TradeBox };