orderly-ui-components

Build trading interfaces using pre-built React components - OrderEntry, Positions, TradingPage, WalletConnect, Sheets, Tables

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "orderly-ui-components" with this command: npx skills add orderlynetwork/skills/orderlynetwork-skills-orderly-ui-components

Orderly Network: UI Components

This skill covers building trading interfaces using Orderly's pre-built React components from @orderly.network/react.

When to Use

  • Rapidly building a trading UI
  • Using pre-built, styled components
  • Implementing standard trading interface patterns

Prerequisites

  • React 18+
  • @orderly.network/react installed
  • Tailwind CSS (recommended for styling)

Installation

npm install @orderly.network/react @orderly.network/hooks @orderly.network/types

# Or with yarn
yarn add @orderly.network/react @orderly.network/hooks @orderly.network/types

Core Providers

Wrap your app with the required providers:

import {
  OrderlyAppProvider,
  TradingPageProvider,
  SymbolProvider,
  WalletConnector
} from '@orderly.network/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <OrderlyAppProvider
        brokerId="woofi_dex"
        chainFilter={[42161, 421614]}
      >
        <SymbolProvider>
          <TradingPageProvider>
            <Layout>
              <WalletConnector />
              <TradingPage />
            </Layout>
          </TradingPageProvider>
        </SymbolProvider>
      </OrderlyAppProvider>
    </QueryClientProvider>
  );
}

Order Entry Component

Basic Order Entry

import { OrderEntry, OrderEntryProvider } from '@orderly.network/ui-order-entry';
import { useOrderEntry } from '@orderly.network/hooks';

function OrderEntryContainer() {
  const { onSubmit } = useOrderEntry();

  const handleSubmit = async (params: any) => {
    try {
      await onSubmit(params);
      console.log('Order submitted');
    } catch (e) {
      console.error('Order failed', e);
    }
  };

  return (
    <div className="bg-gray-900 rounded-lg p-4 border border-gray-800">
      <OrderEntry
        onSubmit={handleSubmit}
        defaultTab="limit"
        hideMarket={false}
      />
    </div>
  );
}

export function OrderEntryWidget() {
  return (
    <OrderEntryProvider symbol="PERP_BTC_USDC">
      <OrderEntryContainer />
    </OrderEntryProvider>
  );
}

Order Entry Props

interface OrderEntryProps {
  onSubmit?: (params: OrderParams) => Promise<void>;
  defaultTab?: 'limit' | 'market';
  hideMarket?: boolean;
  hideLimit?: boolean;
  showLeverage?: boolean;
  className?: string;
}

Positions Component

Basic Positions Table

import { Positions } from '@orderly.network/ui-positions';

export function PositionsWidget() {
  const handleSymbolClick = (symbol: string) => {
    console.log('Navigate to:', symbol);
  };

  return (
    <div className="w-full">
      <Positions
        filter={{ symbol: 'PERP_ETH_USDC' }}  // Optional filter
        onSymbolClick={handleSymbolClick}
        showPagination={true}
      />
    </div>
  );
}

Positions Props

interface PositionsProps {
  filter?: {
    symbol?: string;
    side?: 'BUY' | 'SELL';
  };
  onSymbolClick?: (symbol: string) => void;
  showPagination?: boolean;
  pageSize?: number;
  className?: string;
}

Orderbook Component

import { Orderbook, OrderbookProvider } from '@orderly.network/ui-orderbook';

export function OrderbookWidget({ symbol }: { symbol: string }) {
  return (
    <OrderbookProvider symbol={symbol}>
      <Orderbook
        level={10}           // Number of levels to show
        showTotal={true}     // Show total column
        onItemClick={(price, side) => {
          console.log('Price clicked:', price, side);
        }}
      />
    </OrderbookProvider>
  );
}

Wallet Connect Component

Basic Wallet Connect

import { WalletConnect } from '@orderly.network/react';

export function Header() {
  return (
    <header className="flex justify-between items-center p-4">
      <div className="logo">My DEX</div>
      <WalletConnect />
    </header>
  );
}

Custom Wallet Button

import { useAccount, useWalletConnector } from '@orderly.network/hooks';

export function CustomWalletButton() {
  const { account, state } = useAccount();
  const wallet = useWalletConnector();

  if (state.status !== 'connected') {
    return (
      <button
        onClick={() => wallet.connect()}
        className="btn-primary"
      >
        Connect Wallet
      </button>
    );
  }

  return (
    <div className="wallet-menu">
      <span>{account.address?.slice(0, 6)}...{account.address?.slice(-4)}</span>
      <button onClick={() => wallet.disconnect()}>
        Disconnect
      </button>
    </div>
  );
}

Chart Components

TradingView Widget

import { TradingView } from '@orderly.network/ui-chart';

export function ChartWidget({ symbol }: { symbol: string }) {
  return (
    <div className="h-[500px]">
      <TradingView
        symbol={symbol}
        interval="1h"
        theme="dark"
        autosize={true}
      />
    </div>
  );
}

Lightweight Charts

import { LightweightChart } from '@orderly.network/ui-chart';

export function SimpleChart({ symbol }: { symbol: string }) {
  return (
    <div className="h-[400px]">
      <LightweightChart
        symbol={symbol}
        interval="15m"
        chartType="candlestick"
      />
    </div>
  );
}

Data Table Component

Generic Table

import { Table } from '@orderly.network/ui';

type TradeRow = {
  id: string;
  price: number;
  size: number;
  time: string;
  side: 'BUY' | 'SELL';
};

export function TradesTable({ data }: { data: TradeRow[] }) {
  return (
    <Table<TradeRow>
      dataSource={data}
      columns={[
        {
          title: 'Price',
          dataIndex: 'price',
          render: (value, record) => (
            <span className={record.side === 'BUY' ? 'text-green-500' : 'text-red-500'}>
              {value.toFixed(2)}
            </span>
          ),
        },
        {
          title: 'Size',
          dataIndex: 'size',
          render: (value) => value.toFixed(4),
        },
        {
          title: 'Time',
          dataIndex: 'time',
        },
      ]}
      rowKey="id"
      pagination={{ pageSize: 20 }}
    />
  );
}

Sheet (Drawer) Component

import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetFooter } from '@orderly.network/ui';

export function OrderDetailsSheet({ order }: { order: Order }) {
  return (
    <Sheet>
      <SheetTrigger asChild>
        <button className="btn-secondary">View Details</button>
      </SheetTrigger>
      <SheetContent side="right">
        <SheetHeader>
          <h2>Order Details</h2>
        </SheetHeader>
        <div className="py-4">
          <div className="grid grid-cols-2 gap-2">
            <span>Symbol:</span>
            <span>{order.symbol}</span>
            <span>Side:</span>
            <span>{order.side}</span>
            <span>Price:</span>
            <span>{order.price}</span>
            <span>Quantity:</span>
            <span>{order.order_qty}</span>
            <span>Status:</span>
            <span>{order.status}</span>
          </div>
        </div>
        <SheetFooter>
          <button className="btn-primary">Close Position</button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

Modal Component

import { Modal, ModalTrigger, ModalContent, ModalHeader, ModalBody, ModalFooter } from '@orderly.network/ui';

export function ConfirmOrderModal({ order, onConfirm }: { order: Order; onConfirm: () => void }) {
  return (
    <Modal>
      <ModalTrigger asChild>
        <button className="btn-primary">Place Order</button>
      </ModalTrigger>
      <ModalContent>
        <ModalHeader>
          <h2>Confirm Order</h2>
        </ModalHeader>
        <ModalBody>
          <p>Are you sure you want to place this order?</p>
          <div className="order-summary">
            <p>{order.side} {order.quantity} {order.symbol} @ {order.price}</p>
          </div>
        </ModalBody>
        <ModalFooter>
          <button className="btn-secondary">Cancel</button>
          <button className="btn-primary" onClick={onConfirm}>Confirm</button>
        </ModalFooter>
      </ModalContent>
    </Modal>
  );
}

Empty State Component

import { NoData } from '@orderly.network/ui';

export function EmptyOrders() {
  return (
    <div className="flex flex-col items-center justify-center py-12">
      <NoData width={200} height={200} className="text-gray-500" />
      <p className="mt-4 text-gray-400">No open orders</p>
      <button className="mt-2 btn-secondary">Place Order</button>
    </div>
  );
}

Notification/Toast Component

import { Toast, ToastProvider, useToast } from '@orderly.network/ui';

function TradingPage() {
  const { toast } = useToast();

  const handleOrderSubmit = async () => {
    try {
      await submitOrder();
      toast({
        title: 'Order Placed',
        description: 'Your order has been submitted successfully',
        variant: 'success',
      });
    } catch (error) {
      toast({
        title: 'Order Failed',
        description: error.message,
        variant: 'error',
      });
    }
  };

  return <button onClick={handleOrderSubmit}>Place Order</button>;
}

// In your app root
function App() {
  return (
    <ToastProvider>
      <TradingPage />
    </ToastProvider>
  );
}

Complete Trading Page Example

import {
  OrderlyAppProvider,
  TradingPageProvider,
  SymbolProvider,
  WalletConnect,
} from '@orderly.network/react';
import { OrderEntry, OrderEntryProvider } from '@orderly.network/ui-order-entry';
import { Positions } from '@orderly.network/ui-positions';
import { Orderbook, OrderbookProvider } from '@orderly.network/ui-orderbook';
import { TradingView } from '@orderly.network/ui-chart';
import { useOrderEntry } from '@orderly.network/hooks';

function TradingPage() {
  const symbol = 'PERP_BTC_USDC';

  return (
    <div className="trading-layout">
      {/* Header */}
      <header className="flex justify-between items-center p-4 border-b">
        <h1>My DEX</h1>
        <WalletConnect />
      </header>

      {/* Main Content */}
      <div className="grid grid-cols-12 gap-4 p-4">
        {/* Left: Orderbook */}
        <div className="col-span-2">
          <OrderbookProvider symbol={symbol}>
            <Orderbook level={15} />
          </OrderbookProvider>
        </div>

        {/* Center: Chart + Order Entry */}
        <div className="col-span-7">
          <div className="h-[500px] mb-4">
            <TradingView symbol={symbol} />
          </div>
          <OrderEntryProvider symbol={symbol}>
            <OrderEntry defaultTab="limit" />
          </OrderEntryProvider>
        </div>

        {/* Right: Positions */}
        <div className="col-span-3">
          <Positions showPagination={false} />
        </div>
      </div>
    </div>
  );
}

export function App() {
  return (
    <OrderlyAppProvider brokerId="woofi_dex">
      <SymbolProvider>
        <TradingPageProvider>
          <TradingPage />
        </TradingPageProvider>
      </SymbolProvider>
    </OrderlyAppProvider>
  );
}

Styling

Orderly components use Tailwind CSS classes. Customize with:

/* Override component styles */
.order-entry-root {
  /* Your styles */
}

.positions-table {
  /* Your styles */
}

/* Use Tailwind dark mode */
.dark .order-entry-root {
  /* Dark mode styles */
}

Common Issues

Components not rendering

  • Ensure all providers are wrapped correctly
  • Check that SymbolProvider is above symbol-dependent components
  • Verify Tailwind CSS is configured

Styling conflicts

  • Components use Tailwind utility classes
  • Override with higher-specificity CSS
  • Use className prop when available

Data not updating

  • Check WebSocket connection status
  • Verify account is connected
  • Ensure hooks are called inside provider components

Related Skills

  • orderly-sdk-react-hooks - Hook reference
  • orderly-trading-orders - Order management
  • orderly-websocket-streaming - Real-time data

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

orderly-sdk-wallet-connection

No summary provided by upstream source.

Repository SourceNeeds Review
General

orderly-api-authentication

No summary provided by upstream source.

Repository SourceNeeds Review
General

orderly-deposit-withdraw

No summary provided by upstream source.

Repository SourceNeeds Review