mcpField
O
orderly-sdk-page-components

orderly-sdk-page-components

github.com/orderlynetwork开发249 次安装今天更新
代码仓库

关于 orderly-sdk-page-components

为使用 Orderly SDK 构建 DEX 的开发者介绍预置页面组件及路由组织方式。组件覆盖交易、投资组合、市场、排行榜、积分、金库和联盟页面,并支持响应式界面。

主要功能

  1. 01预置交易与投资组合页面
  2. 02市场列表与资金费率比较
  3. 03排行榜、积分及金库页面
  4. 04联盟仪表盘组件
  5. 05页面懒加载与 Scaffold 布局
  6. 06内置桌面与移动端适配

适用场景

  1. 01快速组装完整 DEX 页面
  2. 02添加持仓、订单和资产页面
  3. 03构建市场、排行榜或积分页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/orderlynetwork/skills --skill orderly-sdk-page-components

安装后在 Claude Code 中输入/orderly-sdk-page-components确认已加载。

详细介绍

Orderly Network:SDK 页面组件

用于构建完整 DEX 的预构建全功能页面组件。每个页面都处理响应式设计(桌面端/移动端)、状态和 UI。在参考模板中,每个页面都会从 app/pages/... 延迟加载,并封装在共享的 Scaffold 布局中。

适用场景

  • 快速构建完整 DEX
  • 使用预构建、可用于生产环境的页面
  • 实现标准 DEX 页面(交易、投资组合、市场、排行榜)

前置条件

  • 已安装 Orderly SDK 软件包(参见 orderly-sdk-install-dependency)
  • 已配置 Providers(参见 orderly-sdk-dex-architecture)
  • React Router v7(react-router-dom)

概览

组件软件包描述
TradingPage@orderly.network/trading完整交易界面(图表、订单簿、下单)
OverviewModule.OverviewPage@orderly.network/portfolio投资组合仪表板
PositionsModule.PositionsPage@orderly.network/portfolio持仓 + 历史记录
OrdersModule.OrdersPage@orderly.network/portfolio订单(未平仓、待处理、已成交)
AssetsModule.AssetsPage@orderly.network/portfolio余额、存款/提现
HistoryModule.HistoryPage@orderly.network/portfolio交易 / 资金费 / 结算历史记录
APIManagerModule.APIManagerPage@orderly.network/portfolioAPI 密钥管理
FeeTierModule.FeeTierPage@orderly.network/portfolio费率等级概览
SettingModule.SettingPage@orderly.network/portfolio账户设置
MarketsHomePage@orderly.network/markets市场列表 + 资金费比较
GeneralLeaderboardWidget@orderly.network/trading-leaderboard交易竞赛排行榜
PointSystemPage@orderly.network/trading-points积分/荣誉计划
VaultsPage@orderly.network/vaultsVault/Earn 产品
Dashboard.DashboardPage@orderly.network/affiliate联盟/推荐仪表板(位于 ReferralProvider 内)

名称很重要。 使用 GeneralLeaderboardWidget(而不是 LeaderboardPage)、PointSystemPage(而不是 TradingRewardsPage;不存在 trading-rewards 软件包)和 VaultsPage。联盟页面是 Dashboard.DashboardPage,不是单独的 Dashboard。

Scaffold 包装模式

参考模板中的每个路由布局都会将 <Outlet/> 封装在来自 @orderly.network/ui-scaffold 的 <Scaffold> 中,并传入导航/页脚配置(在 useOrderlyConfig() 中构建一次)和 routerAdapter。

// app/pages/perp/Layout.tsx
import { Outlet } from 'react-router-dom';
import { Scaffold } from '@orderly.network/ui-scaffold';
import { useOrderlyConfig } from '@/utils/config';
import { useNav } from '@/hooks/useNav';

export default function PerpLayout() {
  const config = useOrderlyConfig();
  const { onRouteChange } = useNav();
  return (
    <Scaffold
      mainNavProps={config.scaffold.mainNavProps}
      footerProps={config.scaffold.footerProps}
      bottomNavProps={config.scaffold.bottomNavProps}
      routerAdapter={{ onRouteChange, currentPath: '/' }}
    >
      <Outlet />
    </Scaffold>
  );
}

每个部分(perp、portfolio、markets、leaderboard、rewards、vaults、swap、points)都有一个采用此模式的 Layout.tsx。

1. TradingPage

由 app/pages/perp/Symbol.tsx 渲染(路由 /perp/:symbol)。tradingViewConfig 和 sharePnLConfig 来自 useOrderlyConfig()(它们根据当前主题和 .env 配置构建)。

// app/pages/perp/Symbol.tsx
import { useCallback, useState } from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { API } from '@orderly.network/types';
import { TradingPage } from '@orderly.network/trading';
import { useOrderlyConfig } from '@/utils/config';

export default function PerpSymbol() {
  const params = useParams();
  const [symbol, setSymbol] = useState(params.symbol!);
  const config = useOrderlyConfig();
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();

  const onSymbolChange = useCallback(
    (data: API.Symbol) => {
      setSymbol(data.symbol);
      const qs = searchParams.toString();
      navigate(`/perp/${data.symbol}${qs ? `?${qs}` : ''}`);
    },
    [navigate, searchParams]
  );

  return (
    <div className="h-full">
      <TradingPage
        symbol={symbol}
        onSymbolChange={onSymbolChange}
        tradingViewConfig={config.tradingPage.tradingViewConfig}
        sharePnLConfig={config.tradingPage.sharePnLConfig}
      />
    </div>
  );
}
tradingViewConfig
tradingViewConfig: {
  scriptSRC: string;      // /tradingview/charting_library/charting_library.js
  library_path: string;   // /tradingview/charting_library/
  customCssUrl?: string;  // /tradingview/chart.css
  colorConfig?: Partial<TradingViewColorConfig>; // only in legacy mode
}

使用 createTradingViewConfig(themeSource) 构建(参见 orderly-sdk-theming)。TradingView 库文件必须放在 public/tradingview/charting_library/ 中。

路由是 /perp/:symbol,而不是 /trade。索引路由 /perp 会重定向到默认交易对。

2. 投资组合页面

投资组合按模块组织,每个模块都导出一个 …Page。模板路由:portfolio(索引)、positions、orders、assets、api-key、fee、history、setting。

import {
  OverviewModule, PositionsModule, OrdersModule, AssetsModule,
  HistoryModule, APIManagerModule, FeeTierModule, SettingModule,
} from '@orderly.network/portfolio';

<OverviewModule.OverviewPage />
<PositionsModule.PositionsPage />
<OrdersModule.OrdersPage sharePnLConfig={config.tradingPage.sharePnLConfig} />
<AssetsModule.AssetsPage />
<HistoryModule.HistoryPage />
<APIManagerModule.APIManagerPage />
<FeeTierModule.FeeTierPage />
<SettingModule.SettingPage />

投资组合路由(延迟加载页面组件,并由共用的 PortfolioLayout 包装,使用 Scaffold):

{
  path: 'portfolio',
  element: <PortfolioLayout />,
  children: [
    { index: true, element: <PortfolioIndex /> },        // OverviewModule.OverviewPage
    { path: 'positions', element: <PortfolioPositions /> },
    { path: 'orders', element: <PortfolioOrders /> },
    { path: 'assets', element: <PortfolioAssets /> },
    { path: 'api-key', element: <PortfolioApiKey /> },   // APIManagerModule.APIManagerPage
    { path: 'fee', element: <PortfolioFee /> },          // FeeTierModule.FeeTierPage
    { path: 'history', element: <PortfolioHistory /> },
    { path: 'setting', element: <PortfolioSetting /> },  // SettingModule.SettingPage
  ],
}

3. MarketsHomePage

import { MarketsHomePage } from '@orderly.network/markets';

<MarketsHomePage
  comparisonProps={{
    // name + icon shown in the funding-comparison list (NOT an exchanges array)
    exchangesName: import.meta.env.VITE_ORDERLY_BROKER_NAME,
    exchangesIconSrc: '/logo-secondary.webp', // optional
  }}
  onSymbolChange={(symbol) => navigate(`/perp/${symbol.symbol}`)}
/>;

comparisonProps 接受 exchangesName 和 exchangesIconSrc(均为可选),而不是 exchanges: string[] 数组。

4. 排行榜

import { GeneralLeaderboardWidget } from '@orderly.network/trading-leaderboard';

export default function LeaderboardIndex() {
  return (
    <div className="oui-py-6 oui-px-4 lg:oui-px-6">
      <GeneralLeaderboardWidget />
    </div>
  );
}

5. 积分 / 奖励

import { PointSystemPage } from '@orderly.network/trading-points';
import { RouteOption } from '@orderly.network/types';

export default function PointsIndex() {
  const navigate = useNavigate();
  const onRouteChange = (p: RouteOption) => {
    if (p.href === '/perp') navigate(`/perp/${getSymbol()}`);
  };
  return <PointSystemPage onRouteChange={onRouteChange} />;
}

6. 金库

import { VaultsPage as VaultsPageComponent } from '@orderly.network/vaults';
<VaultsPageComponent />;

7. 联盟 / 推荐

在 <ReferralProvider> 中渲染 Dashboard.DashboardPage:

import { Dashboard, ReferralProvider } from '@orderly.network/affiliate';

export default function AffiliateIndex() {
  return (
    <ReferralProvider>
      <Dashboard.DashboardPage />
    </ReferralProvider>
  );
}

路由

路由在 app/main.tsx 中通过 createBrowserRouter 定义,basename 为 import.meta.env.BASE_URL。所有页面均采用延迟加载。

const router = createBrowserRouter(
  [
    {
      path: '/',
      element: <App />,
      errorElement: <ErrorBoundary />,
      children: [
        { index: true, element: <IndexPage /> },
        {
          path: 'perp',
          element: <PerpLayout />,
          children: [
            { index: true, element: <PerpIndex /> },
            { path: ':symbol', element: <PerpSymbol /> },
          ],
        },
        {
          path: 'portfolio',
          element: <PortfolioLayout />,
          children: [
            /* …see above… */
          ],
        },
        {
          path: 'markets',
          element: <MarketsLayout />,
          children: [{ index: true, element: <MarketsIndex /> }],
        },
        {
          path: 'leaderboard',
          element: <LeaderboardLayout />,
          children: [{ index: true, element: <LeaderboardIndex /> }],
        },
        {
          path: 'rewards',
          element: <RewardsLayout />,
          children: [
            { index: true, element: <RewardsIndex /> },
            { path: 'affiliate', element: <RewardsAffiliate /> },
          ],
        },
        {
          path: 'vaults',
          element: <VaultsLayout />,
          children: [{ index: true, element: <VaultsIndex /> }],
        },
        {
          path: 'swap',
          element: <SwapLayout />,
          children: [{ index: true, element: <SwapIndex /> }],
        },
        {
          path: 'points',
          element: <PointsLayout />,
          children: [{ index: true, element: <PointsIndex /> }],
        },
      ],
    },
  ],
  { basename: basePath }
);

响应式设计

页面组件会在内部处理桌面端和移动端。对于自定义布局决策,请使用 useScreen()(来自 @orderly.network/ui):

import { useScreen } from '@orderly.network/ui';
const { isMobile } = useScreen();

最佳实践

  1. 延迟加载每个页面(模板在 main.tsx 中延迟导入 app/pages/...)。
  2. 使用 Scaffold 包装路由,确保导航栏、页脚和账户菜单保持一致。
  3. 持久化交易对(模板会在交易对变更时调用 updateSymbol(symbol)),以便深层链接和索引路由能够恢复交易对。
  4. 通过 useOrderlyConfig() 配置 tradingViewConfig / sharePnLConfig,使其跟随当前主题。
  5. 使用 onSymbolChange 更新 URL,让交易页面支持加入书签。

相关技能

  • orderly-sdk-dex-architecture - 项目结构、providers、路由入口
  • orderly-sdk-theming - tradingViewConfig 背后的主题配置
  • orderly-sdk-trading-workflows - 交易功能详情
  • orderly-ui-components - 与这些高级页面相对的细粒度组件

评论

支持 Markdown