@orderly.network/markets 3.0.0-beta.1 → 3.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  var React6 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var hooks = require('@orderly.network/hooks');
6
- var ui = require('@orderly.network/ui');
7
6
  var i18n = require('@orderly.network/i18n');
7
+ var ui = require('@orderly.network/ui');
8
8
  var utils = require('@orderly.network/utils');
9
9
  var ramda = require('ramda');
10
10
  var uiScaffold = require('@orderly.network/ui-scaffold');
@@ -27,7 +27,7 @@ var init_marketsProvider = __esm({
27
27
  "src/components/marketsProvider/index.tsx"() {
28
28
  MarketsContext = React6.createContext({});
29
29
  exports.MarketsProvider = (props) => {
30
- const { symbol, comparisonProps, children, onSymbolChange } = props;
30
+ const { symbol, comparisonProps, children, onSymbolChange, tabs } = props;
31
31
  const [searchValue, setSearchValue] = React6.useState("");
32
32
  const clearSearchValue = React6.useCallback(() => {
33
33
  setSearchValue("");
@@ -39,9 +39,17 @@ var init_marketsProvider = __esm({
39
39
  clearSearchValue,
40
40
  symbol,
41
41
  onSymbolChange,
42
- comparisonProps
42
+ comparisonProps,
43
+ tabs
43
44
  };
44
- }, [searchValue, symbol, onSymbolChange, setSearchValue, comparisonProps]);
45
+ }, [
46
+ searchValue,
47
+ symbol,
48
+ onSymbolChange,
49
+ setSearchValue,
50
+ comparisonProps,
51
+ tabs
52
+ ]);
45
53
  return /* @__PURE__ */ jsxRuntime.jsx(MarketsContext.Provider, { value: memoizedValue, children });
46
54
  };
47
55
  useMarketsContext = () => {
@@ -49,14 +57,63 @@ var init_marketsProvider = __esm({
49
57
  };
50
58
  }
51
59
  });
60
+ var RwaDotTooltip;
61
+ var init_rwaDotTooltip = __esm({
62
+ "src/components/rwaDotTooltip.tsx"() {
63
+ RwaDotTooltip = ({ record }) => {
64
+ const { t } = i18n.useTranslation();
65
+ const isInTradingHours = hooks.isCurrentlyTrading(
66
+ record.rwaNextClose,
67
+ record.rwaStatus
68
+ );
69
+ if (!record.isRwa) {
70
+ return null;
71
+ }
72
+ return /* @__PURE__ */ jsxRuntime.jsx(
73
+ ui.Tooltip,
74
+ {
75
+ content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { color: isInTradingHours ? "success" : "danger", children: isInTradingHours ? t("trading.rwa.marketHours") : t("trading.rwa.outsideMarketHours") }),
76
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { py: 2, px: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
77
+ ui.Box,
78
+ {
79
+ width: 4,
80
+ height: 4,
81
+ r: "full",
82
+ className: isInTradingHours ? "oui-bg-success" : "oui-bg-danger"
83
+ }
84
+ ) })
85
+ }
86
+ );
87
+ };
88
+ }
89
+ });
90
+ var BrokerIdBadge, SymbolBadge;
91
+ var init_symbolBadge = __esm({
92
+ "src/components/symbolBadge.tsx"() {
93
+ BrokerIdBadge = (props) => {
94
+ const { brokerId, brokerName, brokerNameRaw } = hooks.useBadgeBySymbol(
95
+ props.symbol
96
+ );
97
+ const badge = brokerName ?? brokerId ?? void 0;
98
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.SymbolBadge, { badge, fullName: brokerNameRaw });
99
+ };
100
+ SymbolBadge = BrokerIdBadge;
101
+ }
102
+ });
52
103
  exports.SymbolDisplay = void 0;
53
104
  var init_symbolDisplay = __esm({
54
105
  "src/components/symbolDisplay.tsx"() {
106
+ init_rwaDotTooltip();
107
+ init_symbolBadge();
55
108
  exports.SymbolDisplay = React6.memo((props) => {
56
- const { children, size = "xs", ...rest } = props;
109
+ const { children, size = "xs", showBadge = true, record, ...rest } = props;
57
110
  const symbol = children;
58
111
  const symbolsInfo = hooks.useSymbolsInfo();
59
112
  const displayName = symbolsInfo[symbol]("displayName");
113
+ const suffix = record?.isRwa || showBadge ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 0, itemAlign: "center", children: [
114
+ record?.isRwa && /* @__PURE__ */ jsxRuntime.jsx(RwaDotTooltip, { record }),
115
+ showBadge && /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol })
116
+ ] }) : null;
60
117
  if (displayName) {
61
118
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, className: props.className, children: [
62
119
  props.showIcon && /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { size, symbol }),
@@ -68,14 +125,25 @@ var init_symbolDisplay = __esm({
68
125
  className: "oui-whitespace-nowrap oui-break-normal",
69
126
  children: displayName
70
127
  }
71
- )
128
+ ),
129
+ suffix
72
130
  ] });
73
131
  }
74
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.formatted, { size: "xs", rule: "symbol", weight: "semibold", ...rest, children: symbol });
132
+ return /* @__PURE__ */ jsxRuntime.jsx(
133
+ ui.Text.formatted,
134
+ {
135
+ size: "xs",
136
+ rule: "symbol",
137
+ weight: "semibold",
138
+ suffix,
139
+ ...rest,
140
+ children: symbol
141
+ }
142
+ );
75
143
  });
76
144
  }
77
145
  });
78
- var EditIcon, TrashIcon, AllMarketsIcon, NewListingsIcon, FavoritesIcon, UnFavoritesIcon, SearchIcon, MoveToTopIcon, OrderlyIcon, FavoritesIcon2, UnFavoritesIcon2, TopIcon, DeleteIcon, AddIcon, ActiveAddIcon, ExpandIcon, CollapseIcon, FilterIcon, TriangleDownIcon, ArrowLeftIcon;
146
+ var EditIcon, TrashIcon, AllMarketsIcon, NewListingsIcon, FavoritesIcon, UnFavoritesIcon, SearchIcon, MoveToTopIcon, OrderlyIcon, FavoritesIcon2, UnFavoritesIcon2, TopIcon, DeleteIcon, AddIcon, ActiveAddIcon, FilterIcon, TriangleDownIcon, ArrowLeftIcon;
79
147
  var init_icons = __esm({
80
148
  "src/icons.tsx"() {
81
149
  EditIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -372,30 +440,6 @@ var init_icons = __esm({
372
440
  ]
373
441
  }
374
442
  );
375
- ExpandIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
376
- "svg",
377
- {
378
- width: "16",
379
- height: "16",
380
- viewBox: "0 0 16 16",
381
- fill: "currentColor",
382
- xmlns: "http://www.w3.org/2000/svg",
383
- ...props,
384
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.326 8.826a.84.84 0 0 0-.6.234L2.16 12.627v-2.135H.492v4.167c0 .46.373.833.834.833h4.166v-1.667H3.357l3.567-3.567a.857.857 0 0 0 0-1.198.84.84 0 0 0-.598-.234M10.502.492V2.16h2.135L9.07 5.726a.857.857 0 0 0 0 1.199.86.86 0 0 0 1.197 0l3.568-3.568v2.135h1.667V1.326a.834.834 0 0 0-.834-.834z" })
385
- }
386
- );
387
- CollapseIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
388
- "svg",
389
- {
390
- width: "16",
391
- height: "16",
392
- viewBox: "0 0 16 16",
393
- fill: "currentColor",
394
- xmlns: "http://www.w3.org/2000/svg",
395
- ...props,
396
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.668.492a.85.85 0 0 0-.599.234l-3.567 3.568V2.159H8.835v4.167c0 .46.373.833.833.833h4.167V5.492H11.7l3.569-3.567a.86.86 0 0 0 0-1.199.85.85 0 0 0-.6-.234m-12.5 8.334v1.666h2.135L.736 14.06a.86.86 0 0 0 0 1.198.86.86 0 0 0 1.198 0l3.568-3.567v2.134h1.666V9.66a.834.834 0 0 0-.833-.833z" })
397
- }
398
- );
399
443
  FilterIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
400
444
  "svg",
401
445
  {
@@ -1082,6 +1126,101 @@ var init_marketsHeader_widget = __esm({
1082
1126
  };
1083
1127
  }
1084
1128
  });
1129
+ function createCommunityBrokerFilter(selected) {
1130
+ return (data) => selected === "all" ? data?.filter((m) => Boolean(m?.broker_id)) : data?.filter((m) => m?.broker_id === selected);
1131
+ }
1132
+ function useCommunityTabs() {
1133
+ const brokerId = hooks.useConfig("brokerId");
1134
+ const [brokers] = hooks.useAllBrokers();
1135
+ const [allMarkets] = hooks.useMarkets(hooks.MarketsType.ALL);
1136
+ const lastSignatureRef = React6.useRef("");
1137
+ const lastValueRef = React6.useRef([]);
1138
+ return React6.useMemo(() => {
1139
+ const brokerIdSet = /* @__PURE__ */ new Set();
1140
+ for (const m of allMarkets ?? []) {
1141
+ const id = m?.broker_id;
1142
+ if (typeof id === "string" && id.length) {
1143
+ brokerIdSet.add(id);
1144
+ }
1145
+ }
1146
+ const entries = Array.from(
1147
+ brokerIdSet
1148
+ ).map((id) => ({
1149
+ id,
1150
+ name: brokers?.[id]
1151
+ }));
1152
+ const sorted = entries.map(({ id, name }) => ({
1153
+ id,
1154
+ label: name ?? id,
1155
+ sortKey: (name ?? id).toLowerCase()
1156
+ })).sort((a, b) => a.sortKey.localeCompare(b.sortKey));
1157
+ if (brokerId) {
1158
+ const idx = sorted.findIndex((x) => x.id === brokerId);
1159
+ if (idx > 0) {
1160
+ const [cur] = sorted.splice(idx, 1);
1161
+ sorted.unshift(cur);
1162
+ }
1163
+ }
1164
+ const signature = sorted.map((x) => `${x.id}:${x.label}`).join("|");
1165
+ if (signature === lastSignatureRef.current) {
1166
+ return lastValueRef.current;
1167
+ }
1168
+ lastSignatureRef.current = signature;
1169
+ lastValueRef.current = sorted;
1170
+ return sorted;
1171
+ }, [allMarkets, brokers, brokerId]);
1172
+ }
1173
+ var init_useCommunityTabs = __esm({
1174
+ "src/hooks/useCommunityTabs.ts"() {
1175
+ }
1176
+ });
1177
+ var CommunityBrokerTabs;
1178
+ var init_communityBrokerTabs_ui = __esm({
1179
+ "src/components/communityBrokerTabs/communityBrokerTabs.ui.tsx"() {
1180
+ init_useCommunityTabs();
1181
+ CommunityBrokerTabs = (props) => {
1182
+ const {
1183
+ storageKey,
1184
+ className,
1185
+ classNames,
1186
+ variant = "contained",
1187
+ size = "sm",
1188
+ showScrollIndicator,
1189
+ allTitle,
1190
+ renderPanel
1191
+ } = props;
1192
+ const { t } = i18n.useTranslation();
1193
+ const [communitySubTab, setCommunitySubTab] = hooks.useLocalStorage(
1194
+ storageKey,
1195
+ "all"
1196
+ );
1197
+ const communityBrokerTabs = useCommunityTabs();
1198
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1199
+ ui.Tabs,
1200
+ {
1201
+ variant,
1202
+ size,
1203
+ value: communitySubTab,
1204
+ onValueChange: setCommunitySubTab,
1205
+ classNames,
1206
+ className,
1207
+ showScrollIndicator,
1208
+ children: [
1209
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TabPanel, { title: allTitle ?? t("common.all"), value: "all", children: renderPanel("all") }),
1210
+ communityBrokerTabs.map((b) => /* @__PURE__ */ jsxRuntime.jsx(ui.TabPanel, { title: b.label, value: b.id, children: renderPanel(b.id) }, b.id))
1211
+ ]
1212
+ }
1213
+ );
1214
+ };
1215
+ }
1216
+ });
1217
+
1218
+ // src/components/communityBrokerTabs/index.ts
1219
+ var init_communityBrokerTabs = __esm({
1220
+ "src/components/communityBrokerTabs/index.ts"() {
1221
+ init_communityBrokerTabs_ui();
1222
+ }
1223
+ });
1085
1224
  exports.CollapseMarkets = void 0;
1086
1225
  var init_collapseMarkets = __esm({
1087
1226
  "src/components/collapseMarkets/index.tsx"() {
@@ -1182,6 +1321,7 @@ var init_collapseMarkets = __esm({
1182
1321
  exports.FavoritesDropdownMenu = void 0;
1183
1322
  var init_favoritesDropdownMenu_ui = __esm({
1184
1323
  "src/components/favoritesDropdownMenu/favoritesDropdownMenu.ui.tsx"() {
1324
+ init_symbolBadge();
1185
1325
  exports.FavoritesDropdownMenu = (props) => {
1186
1326
  const {
1187
1327
  symbol,
@@ -1293,9 +1433,10 @@ var init_favoritesDropdownMenu_ui = __esm({
1293
1433
  ui.Text.formatted,
1294
1434
  {
1295
1435
  rule: "symbol",
1296
- formatString: "base-type",
1436
+ formatString: "base",
1297
1437
  size: "base",
1298
1438
  showIcon: true,
1439
+ suffix: /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol }),
1299
1440
  children: symbol
1300
1441
  }
1301
1442
  )
@@ -1507,185 +1648,233 @@ var init_favoritesDropdownMenu = __esm({
1507
1648
  init_favoritesDropdownMenu_widget();
1508
1649
  }
1509
1650
  });
1510
- var RwaDotTooltip;
1511
- var init_rwaDotTooltip = __esm({
1512
- "src/components/rwaDotTooltip.tsx"() {
1513
- RwaDotTooltip = ({ record }) => {
1514
- const { t } = i18n.useTranslation();
1515
- const isInTradingHours = hooks.isCurrentlyTrading(
1516
- record.rwaNextClose,
1517
- record.rwaStatus
1518
- );
1519
- if (!record.isRwa) {
1520
- return null;
1651
+ function getSymbolColumn(favorite, isFavoriteList = false, options) {
1652
+ return {
1653
+ title: i18n.i18n.t("common.symbol"),
1654
+ dataIndex: "symbol",
1655
+ width: 150,
1656
+ onSort: true,
1657
+ render: (value, record) => {
1658
+ let favoritesIcon;
1659
+ if (!isFavoriteList) {
1660
+ favoritesIcon = /* @__PURE__ */ jsxRuntime.jsx(exports.FavoritesDropdownMenuWidget, { row: record, favorite, children: /* @__PURE__ */ jsxRuntime.jsx(
1661
+ ui.Flex,
1662
+ {
1663
+ width: 12,
1664
+ height: 12,
1665
+ justify: "center",
1666
+ itemAlign: "center",
1667
+ className: "oui-mr-1 oui-cursor-pointer",
1668
+ children: record.isFavorite ? /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon2, { className: "oui-size-3" }) : /* @__PURE__ */ jsxRuntime.jsx(UnFavoritesIcon2, { className: "oui-size-3" })
1669
+ }
1670
+ ) });
1521
1671
  }
1672
+ const stackLeverageInSecondRow = options?.stackLeverageInSecondRow;
1673
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, itemAlign: "center", children: [
1674
+ favoritesIcon,
1675
+ /* @__PURE__ */ jsxRuntime.jsxs(
1676
+ ui.Flex,
1677
+ {
1678
+ direction: stackLeverageInSecondRow ? "column" : "row",
1679
+ itemAlign: stackLeverageInSecondRow ? "start" : "center",
1680
+ gapY: stackLeverageInSecondRow ? 1 : void 0,
1681
+ gapX: stackLeverageInSecondRow ? void 0 : 1,
1682
+ children: [
1683
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, itemAlign: "center", children: [
1684
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: value, className: "oui-size-[18px]" }),
1685
+ /* @__PURE__ */ jsxRuntime.jsx(exports.SymbolDisplay, { formatString: "base", size: "2xs", record, children: value })
1686
+ ] }),
1687
+ typeof record.leverage === "number" && /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "xs", color: "primary", children: [
1688
+ record.leverage,
1689
+ "x"
1690
+ ] })
1691
+ ]
1692
+ }
1693
+ )
1694
+ ] });
1695
+ }
1696
+ };
1697
+ }
1698
+ function getLastColumn() {
1699
+ return {
1700
+ title: i18n.i18n.t("markets.column.last"),
1701
+ dataIndex: "24h_close",
1702
+ align: "right",
1703
+ onSort: true,
1704
+ width: 100,
1705
+ render: (value, record) => {
1706
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: value });
1707
+ }
1708
+ };
1709
+ }
1710
+ function get24hPercentageColumn() {
1711
+ return {
1712
+ title: i18n.i18n.t("markets.column.24hPercentage"),
1713
+ dataIndex: "change",
1714
+ align: "right",
1715
+ onSort: true,
1716
+ width: 80,
1717
+ render: (value) => {
1522
1718
  return /* @__PURE__ */ jsxRuntime.jsx(
1523
- ui.Tooltip,
1719
+ ui.Text.numeral,
1524
1720
  {
1525
- content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { color: isInTradingHours ? "success" : "danger", children: isInTradingHours ? t("trading.rwa.marketHours") : t("trading.rwa.outsideMarketHours") }),
1526
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { p: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
1527
- ui.Box,
1528
- {
1529
- width: 4,
1530
- height: 4,
1531
- r: "full",
1532
- className: isInTradingHours ? "oui-bg-success" : "oui-bg-danger"
1533
- }
1534
- ) })
1721
+ rule: "percentages",
1722
+ coloring: true,
1723
+ rm: utils.Decimal.ROUND_DOWN,
1724
+ showIdentifier: true,
1725
+ size: "2xs",
1726
+ children: value
1535
1727
  }
1536
1728
  );
1537
- };
1538
- }
1539
- });
1540
- var useSideMarketsColumns;
1541
- var init_column = __esm({
1542
- "src/components/sideMarkets/column.tsx"() {
1543
- init_icons();
1544
- init_favoritesDropdownMenu();
1545
- init_rwaDotTooltip();
1546
- init_symbolDisplay();
1547
- useSideMarketsColumns = (favorite, isFavoriteList = false) => {
1548
- const { t } = i18n.useTranslation();
1549
- return [
1729
+ }
1730
+ };
1731
+ }
1732
+ function get24hVolOIColumn() {
1733
+ return {
1734
+ title: i18n.i18n.t("markets.column.24hVolOI"),
1735
+ dataIndex: "24h_amount",
1736
+ align: "right",
1737
+ className: "oui-h-[36px]",
1738
+ width: 100,
1739
+ multiSort: {
1740
+ fields: [
1550
1741
  {
1551
- title: `${t("markets.column.market")} / ${t("common.volume")}`,
1552
- dataIndex: "24h_amount",
1553
- multiSort: {
1554
- fields: [
1555
- {
1556
- sortKey: "symbol",
1557
- label: t("markets.column.market")
1558
- },
1559
- {
1560
- sortKey: "24h_amount",
1561
- label: t("common.volume")
1562
- }
1563
- ]
1564
- },
1565
- className: "oui-h-[36px]",
1566
- render: (value, record) => {
1567
- let favoritesIcon;
1568
- if (!isFavoriteList) {
1569
- favoritesIcon = /* @__PURE__ */ jsxRuntime.jsx(exports.FavoritesDropdownMenuWidget, { row: record, favorite, children: /* @__PURE__ */ jsxRuntime.jsx(
1570
- ui.Flex,
1571
- {
1572
- width: 12,
1573
- height: 12,
1574
- justify: "center",
1575
- itemAlign: "center",
1576
- className: "oui-mr-1 oui-cursor-pointer",
1577
- children: record.isFavorite ? /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon2, { className: "oui-size-3" }) : /* @__PURE__ */ jsxRuntime.jsx(UnFavoritesIcon2, { className: "oui-size-3" })
1578
- }
1579
- ) });
1580
- }
1581
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
1582
- favoritesIcon,
1583
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", gapY: 1, children: [
1584
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1585
- /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: record.symbol, className: "oui-size-[18px]" }),
1586
- /* @__PURE__ */ jsxRuntime.jsx(exports.SymbolDisplay, { formatString: "base", size: "2xs", children: record.symbol }),
1587
- /* @__PURE__ */ jsxRuntime.jsx(RwaDotTooltip, { record }),
1588
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "xs", color: "primary", children: [
1589
- record.leverage,
1590
- "x"
1591
- ] })
1592
- ] }),
1593
- /* @__PURE__ */ jsxRuntime.jsx(
1594
- ui.Text.numeral,
1595
- {
1596
- intensity: 54,
1597
- size: "2xs",
1598
- rule: "human",
1599
- dp: 2,
1600
- rm: utils.Decimal.ROUND_DOWN,
1601
- children: value
1602
- }
1603
- )
1604
- ] })
1605
- ] });
1606
- }
1742
+ sortKey: "24h_amount",
1743
+ label: i18n.i18n.t("markets.column.24hVol")
1607
1744
  },
1608
1745
  {
1609
- title: t("markets.column.price&Change"),
1610
- dataIndex: "change",
1611
- align: "right",
1612
- onSort: true,
1613
- className: "oui-h-[36px]",
1614
- render: (value, record) => {
1615
- const onDelSymbol = (e) => {
1616
- favorite.updateSymbolFavoriteState(
1617
- record,
1618
- favorite.selectedFavoriteTab,
1619
- true
1620
- );
1621
- e.stopPropagation();
1622
- };
1623
- const iconCls = "oui-w-4 oui-h-4 oui-text-base-contrast-54 hover:oui-text-base-contrast";
1624
- const actions = /* @__PURE__ */ jsxRuntime.jsx(
1625
- "div",
1626
- {
1627
- className: ui.cn(
1628
- "oui-absolute oui-right-0 oui-top-[6.5px]",
1629
- "oui-hidden group-hover:oui-block"
1630
- ),
1631
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1632
- ui.Flex,
1633
- {
1634
- className: ui.cn(
1635
- "oui-inline-flex",
1636
- "oui-bg-primary-darken oui-py-[6px]"
1637
- ),
1638
- r: "base",
1639
- width: 52,
1640
- justify: "center",
1641
- itemAlign: "end",
1642
- gapX: 2,
1643
- children: [
1644
- /* @__PURE__ */ jsxRuntime.jsx(
1645
- TopIcon,
1646
- {
1647
- className: iconCls,
1648
- onClick: (e) => {
1649
- e.stopPropagation();
1650
- favorite.pinToTop(record);
1651
- }
1652
- }
1653
- ),
1654
- /* @__PURE__ */ jsxRuntime.jsx(DeleteIcon, { className: iconCls, onClick: onDelSymbol })
1655
- ]
1746
+ sortKey: "openInterest",
1747
+ label: i18n.i18n.t("markets.column.OI")
1748
+ }
1749
+ ]
1750
+ },
1751
+ render: (value, record) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "end", gapY: 1, children: [
1752
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, rm: utils.Decimal.ROUND_DOWN, children: value }),
1753
+ /* @__PURE__ */ jsxRuntime.jsx(
1754
+ ui.Text.numeral,
1755
+ {
1756
+ rule: "human",
1757
+ dp: 2,
1758
+ rm: utils.Decimal.ROUND_DOWN,
1759
+ size: "2xs",
1760
+ intensity: 54,
1761
+ children: record.openInterest
1762
+ }
1763
+ )
1764
+ ] })
1765
+ };
1766
+ }
1767
+ function getLastAnd24hPercentageColumn(favorite, isFavoriteList = false) {
1768
+ return {
1769
+ title: i18n.i18n.t("markets.column.last&24hPercentage"),
1770
+ dataIndex: "change",
1771
+ align: "right",
1772
+ onSort: true,
1773
+ className: "oui-h-[36px]",
1774
+ width: 100,
1775
+ render: (value, record) => {
1776
+ const onDelSymbol = (e) => {
1777
+ favorite.updateSymbolFavoriteState(
1778
+ record,
1779
+ favorite.selectedFavoriteTab,
1780
+ true
1781
+ );
1782
+ e.stopPropagation();
1783
+ };
1784
+ const iconCls = "oui-w-4 oui-h-4 oui-text-base-contrast-54 hover:oui-text-base-contrast";
1785
+ const actions = /* @__PURE__ */ jsxRuntime.jsx(
1786
+ "div",
1787
+ {
1788
+ className: ui.cn(
1789
+ "oui-absolute oui-right-0 oui-top-[6.5px]",
1790
+ "oui-hidden group-hover:oui-block"
1791
+ ),
1792
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1793
+ ui.Flex,
1794
+ {
1795
+ className: ui.cn(
1796
+ "oui-inline-flex",
1797
+ "oui-bg-primary-darken oui-py-[6px]"
1798
+ ),
1799
+ r: "base",
1800
+ width: 52,
1801
+ justify: "center",
1802
+ itemAlign: "end",
1803
+ gapX: 2,
1804
+ children: [
1805
+ /* @__PURE__ */ jsxRuntime.jsx(
1806
+ TopIcon,
1807
+ {
1808
+ className: iconCls,
1809
+ onClick: (e) => {
1810
+ e.stopPropagation();
1811
+ favorite.pinToTop(record);
1812
+ }
1656
1813
  }
1657
- )
1658
- }
1659
- );
1660
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-relative", children: [
1661
- isFavoriteList && actions,
1662
- /* @__PURE__ */ jsxRuntime.jsxs(
1663
- ui.Flex,
1814
+ ),
1815
+ /* @__PURE__ */ jsxRuntime.jsx(DeleteIcon, { className: iconCls, onClick: onDelSymbol })
1816
+ ]
1817
+ }
1818
+ )
1819
+ }
1820
+ );
1821
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-relative", children: [
1822
+ isFavoriteList && actions,
1823
+ /* @__PURE__ */ jsxRuntime.jsxs(
1824
+ ui.Flex,
1825
+ {
1826
+ direction: "column",
1827
+ justify: "end",
1828
+ itemAlign: "end",
1829
+ gapY: 1,
1830
+ className: ui.cn(isFavoriteList && "group-hover:oui-invisible"),
1831
+ children: [
1832
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: record["24h_close"] }),
1833
+ /* @__PURE__ */ jsxRuntime.jsx(
1834
+ ui.Text.numeral,
1664
1835
  {
1665
- direction: "column",
1666
- justify: "end",
1667
- itemAlign: "end",
1668
- gapY: 1,
1669
- className: ui.cn(isFavoriteList && "group-hover:oui-invisible"),
1670
- children: [
1671
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: record["24h_close"] }),
1672
- /* @__PURE__ */ jsxRuntime.jsx(
1673
- ui.Text.numeral,
1674
- {
1675
- rule: "percentages",
1676
- coloring: true,
1677
- rm: utils.Decimal.ROUND_DOWN,
1678
- showIdentifier: true,
1679
- size: "2xs",
1680
- children: value
1681
- }
1682
- )
1683
- ]
1836
+ rule: "percentages",
1837
+ coloring: true,
1838
+ rm: utils.Decimal.ROUND_DOWN,
1839
+ showIdentifier: true,
1840
+ size: "2xs",
1841
+ children: value
1684
1842
  }
1685
1843
  )
1686
- ] });
1844
+ ]
1687
1845
  }
1688
- }
1846
+ )
1847
+ ] });
1848
+ }
1849
+ };
1850
+ }
1851
+ var init_column = __esm({
1852
+ "src/components/shared/column.tsx"() {
1853
+ init_icons();
1854
+ init_icons();
1855
+ init_favoritesDropdownMenu();
1856
+ init_symbolDisplay();
1857
+ }
1858
+ });
1859
+
1860
+ // src/components/sideMarkets/column.tsx
1861
+ var useSideMarketsColumns;
1862
+ var init_column2 = __esm({
1863
+ "src/components/sideMarkets/column.tsx"() {
1864
+ init_column();
1865
+ useSideMarketsColumns = (favorite, isFavoriteList = false) => {
1866
+ const symbolCol = getSymbolColumn(favorite, isFavoriteList, {
1867
+ stackLeverageInSecondRow: true
1868
+ });
1869
+ const volOiCol = get24hVolOIColumn();
1870
+ const lastPctCol = getLastAnd24hPercentageColumn(favorite, isFavoriteList);
1871
+ return [
1872
+ {
1873
+ ...symbolCol,
1874
+ width: 115
1875
+ },
1876
+ volOiCol,
1877
+ lastPctCol
1689
1878
  ];
1690
1879
  };
1691
1880
  }
@@ -1695,7 +1884,7 @@ var init_marketsList_ui = __esm({
1695
1884
  "src/components/marketsList/marketsList.ui.tsx"() {
1696
1885
  init_collapseMarkets();
1697
1886
  init_marketsProvider();
1698
- init_column();
1887
+ init_column2();
1699
1888
  exports.MarketsList = (props) => {
1700
1889
  const {
1701
1890
  loading,
@@ -1756,7 +1945,7 @@ var init_marketsList_ui = __esm({
1756
1945
  });
1757
1946
 
1758
1947
  // src/type.ts
1759
- exports.MarketsPageTab = void 0; exports.MarketsTabName = void 0; exports.FundingTabName = void 0;
1948
+ exports.MarketsPageTab = void 0; exports.MarketsTabName = void 0; exports.CommunitySubTabName = void 0; exports.FundingTabName = void 0;
1760
1949
  var init_type = __esm({
1761
1950
  "src/type.ts"() {
1762
1951
  exports.MarketsPageTab = /* @__PURE__ */ ((MarketsPageTab2) => {
@@ -1770,8 +1959,15 @@ var init_type = __esm({
1770
1959
  MarketsTabName2["All"] = "all";
1771
1960
  MarketsTabName2["Rwa"] = "rwa";
1772
1961
  MarketsTabName2["NewListing"] = "newListing";
1962
+ MarketsTabName2["Community"] = "community";
1773
1963
  return MarketsTabName2;
1774
1964
  })(exports.MarketsTabName || {});
1965
+ exports.CommunitySubTabName = /* @__PURE__ */ ((CommunitySubTabName2) => {
1966
+ CommunitySubTabName2["All"] = "all";
1967
+ CommunitySubTabName2["MyListings"] = "myListings";
1968
+ CommunitySubTabName2["OtherListings"] = "otherListings";
1969
+ return CommunitySubTabName2;
1970
+ })(exports.CommunitySubTabName || {});
1775
1971
  exports.FundingTabName = /* @__PURE__ */ ((FundingTabName2) => {
1776
1972
  FundingTabName2["Overview"] = "overview";
1777
1973
  FundingTabName2["Comparison"] = "comparison";
@@ -1787,6 +1983,7 @@ var init_marketsList_script = __esm({
1787
1983
  init_marketsProvider();
1788
1984
  MarketsTypeMap = {
1789
1985
  ["all" /* All */]: hooks.MarketsType.ALL,
1986
+ ["community" /* Community */]: hooks.MarketsType.COMMUNITY,
1790
1987
  ["rwa" /* Rwa */]: hooks.MarketsType.RWA,
1791
1988
  ["favorites" /* Favorites */]: hooks.MarketsType.FAVORITES,
1792
1989
  ["recent" /* Recent */]: hooks.MarketsType.RECENT,
@@ -1886,18 +2083,7 @@ var init_rwaTab = __esm({
1886
2083
  };
1887
2084
  RwaTab = () => {
1888
2085
  const { t } = i18n.useTranslation();
1889
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
1890
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.rwa") }),
1891
- /* @__PURE__ */ jsxRuntime.jsx(
1892
- ui.Box,
1893
- {
1894
- r: "base",
1895
- px: 2,
1896
- className: "oui-bg-gradient-to-r oui-from-[rgb(var(--oui-gradient-brand-start)_/_0.12)] oui-to-[rgb(var(--oui-gradient-brand-end)_/_0.12)]",
1897
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.GradientText, { color: "brand", children: t("common.new") })
1898
- }
1899
- )
1900
- ] });
2086
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gap: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.rwa") }) });
1901
2087
  };
1902
2088
  }
1903
2089
  });
@@ -1959,231 +2145,6 @@ var init_searchInput = __esm({
1959
2145
  };
1960
2146
  }
1961
2147
  });
1962
- function getSymbolColumn(favorite, isFavoriteList = false) {
1963
- return {
1964
- title: i18n.i18n.t("common.symbol"),
1965
- dataIndex: "symbol",
1966
- width: 150,
1967
- onSort: true,
1968
- render: (value, record) => {
1969
- let favoritesIcon;
1970
- if (!isFavoriteList) {
1971
- favoritesIcon = /* @__PURE__ */ jsxRuntime.jsx(exports.FavoritesDropdownMenuWidget, { row: record, favorite, children: /* @__PURE__ */ jsxRuntime.jsx(
1972
- ui.Flex,
1973
- {
1974
- width: 12,
1975
- height: 12,
1976
- justify: "center",
1977
- itemAlign: "center",
1978
- className: "oui-mr-1 oui-cursor-pointer",
1979
- children: record.isFavorite ? /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon2, { className: "oui-size-3" }) : /* @__PURE__ */ jsxRuntime.jsx(UnFavoritesIcon2, { className: "oui-size-3" })
1980
- }
1981
- ) });
1982
- }
1983
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1984
- favoritesIcon,
1985
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", gapY: 1, children: [
1986
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, itemAlign: "center", children: [
1987
- /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: value, className: "oui-size-[18px]" }),
1988
- /* @__PURE__ */ jsxRuntime.jsx(exports.SymbolDisplay, { formatString: "base", size: "2xs", children: value }),
1989
- /* @__PURE__ */ jsxRuntime.jsx(RwaDotTooltip, { record })
1990
- ] }),
1991
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "xs", color: "primary", children: [
1992
- record.leverage,
1993
- "x"
1994
- ] })
1995
- ] })
1996
- ] });
1997
- }
1998
- };
1999
- }
2000
- function getLastColumn() {
2001
- return {
2002
- title: i18n.i18n.t("markets.column.last"),
2003
- dataIndex: "24h_close",
2004
- align: "right",
2005
- onSort: true,
2006
- width: 100,
2007
- render: (value, record) => {
2008
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: value });
2009
- }
2010
- };
2011
- }
2012
- function get24hPercentageColumn() {
2013
- return {
2014
- title: i18n.i18n.t("markets.column.24hPercentage"),
2015
- dataIndex: "change",
2016
- align: "right",
2017
- onSort: true,
2018
- width: 80,
2019
- render: (value) => {
2020
- return /* @__PURE__ */ jsxRuntime.jsx(
2021
- ui.Text.numeral,
2022
- {
2023
- rule: "percentages",
2024
- coloring: true,
2025
- rm: utils.Decimal.ROUND_DOWN,
2026
- showIdentifier: true,
2027
- size: "2xs",
2028
- children: value
2029
- }
2030
- );
2031
- }
2032
- };
2033
- }
2034
- function get24hVolOIColumn() {
2035
- return {
2036
- title: i18n.i18n.t("markets.column.24hVolOI"),
2037
- dataIndex: "24h_amount",
2038
- align: "right",
2039
- className: "oui-h-[36px]",
2040
- width: 100,
2041
- multiSort: {
2042
- fields: [
2043
- {
2044
- sortKey: "24h_amount",
2045
- label: i18n.i18n.t("markets.column.24hVol")
2046
- },
2047
- {
2048
- sortKey: "openInterest",
2049
- label: i18n.i18n.t("markets.column.OI")
2050
- }
2051
- ]
2052
- },
2053
- render: (value, record) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "end", gapY: 1, children: [
2054
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, rm: utils.Decimal.ROUND_DOWN, children: value }),
2055
- /* @__PURE__ */ jsxRuntime.jsx(
2056
- ui.Text.numeral,
2057
- {
2058
- rule: "human",
2059
- dp: 2,
2060
- rm: utils.Decimal.ROUND_DOWN,
2061
- size: "2xs",
2062
- intensity: 54,
2063
- children: record.openInterest
2064
- }
2065
- )
2066
- ] })
2067
- };
2068
- }
2069
- function getLastAnd24hPercentageColumn(favorite, isFavoriteList = false) {
2070
- return {
2071
- title: i18n.i18n.t("markets.column.last&24hPercentage"),
2072
- dataIndex: "change",
2073
- align: "right",
2074
- onSort: true,
2075
- className: "oui-h-[36px]",
2076
- width: 100,
2077
- render: (value, record) => {
2078
- const onDelSymbol = (e) => {
2079
- favorite.updateSymbolFavoriteState(
2080
- record,
2081
- favorite.selectedFavoriteTab,
2082
- true
2083
- );
2084
- e.stopPropagation();
2085
- };
2086
- const iconCls = "oui-w-4 oui-h-4 oui-text-base-contrast-54 hover:oui-text-base-contrast";
2087
- const actions = /* @__PURE__ */ jsxRuntime.jsx(
2088
- "div",
2089
- {
2090
- className: ui.cn(
2091
- "oui-absolute oui-right-0 oui-top-[6.5px]",
2092
- "oui-hidden group-hover:oui-block"
2093
- ),
2094
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2095
- ui.Flex,
2096
- {
2097
- className: ui.cn(
2098
- "oui-inline-flex",
2099
- "oui-bg-primary-darken oui-py-[6px]"
2100
- ),
2101
- r: "base",
2102
- width: 52,
2103
- justify: "center",
2104
- itemAlign: "end",
2105
- gapX: 2,
2106
- children: [
2107
- /* @__PURE__ */ jsxRuntime.jsx(
2108
- TopIcon,
2109
- {
2110
- className: iconCls,
2111
- onClick: (e) => {
2112
- e.stopPropagation();
2113
- favorite.pinToTop(record);
2114
- }
2115
- }
2116
- ),
2117
- /* @__PURE__ */ jsxRuntime.jsx(DeleteIcon, { className: iconCls, onClick: onDelSymbol })
2118
- ]
2119
- }
2120
- )
2121
- }
2122
- );
2123
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-relative", children: [
2124
- isFavoriteList && actions,
2125
- /* @__PURE__ */ jsxRuntime.jsxs(
2126
- ui.Flex,
2127
- {
2128
- direction: "column",
2129
- justify: "end",
2130
- itemAlign: "end",
2131
- gapY: 1,
2132
- className: ui.cn(isFavoriteList && "group-hover:oui-invisible"),
2133
- children: [
2134
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: record["24h_close"] }),
2135
- /* @__PURE__ */ jsxRuntime.jsx(
2136
- ui.Text.numeral,
2137
- {
2138
- rule: "percentages",
2139
- coloring: true,
2140
- rm: utils.Decimal.ROUND_DOWN,
2141
- showIdentifier: true,
2142
- size: "2xs",
2143
- children: value
2144
- }
2145
- )
2146
- ]
2147
- }
2148
- )
2149
- ] });
2150
- }
2151
- };
2152
- }
2153
- function getMarkIndexColumn() {
2154
- return {
2155
- title: i18n.i18n.t("markets.column.mark&Index"),
2156
- dataIndex: "mark_price",
2157
- align: "right",
2158
- className: "oui-h-[36px]",
2159
- width: 100,
2160
- multiSort: {
2161
- fields: [
2162
- {
2163
- sortKey: "mark_price",
2164
- label: i18n.i18n.t("markets.column.mark")
2165
- },
2166
- {
2167
- sortKey: "index_price",
2168
- label: i18n.i18n.t("markets.column.index")
2169
- }
2170
- ]
2171
- },
2172
- render: (value, record) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "end", gapY: 1, children: [
2173
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", children: value }),
2174
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, size: "2xs", intensity: 54, children: record.index_price })
2175
- ] })
2176
- };
2177
- }
2178
- var init_column2 = __esm({
2179
- "src/components/shared/column.tsx"() {
2180
- init_icons();
2181
- init_icons();
2182
- init_favoritesDropdownMenu();
2183
- init_rwaDotTooltip();
2184
- init_symbolDisplay();
2185
- }
2186
- });
2187
2148
  var FavoritesEmpty;
2188
2149
  var init_favoritesEmpty = __esm({
2189
2150
  "src/components/favoritesEmpty/index.tsx"() {
@@ -2635,31 +2596,181 @@ var init_useFavoritesExtraProps = __esm({
2635
2596
  init_marketsProvider();
2636
2597
  }
2637
2598
  });
2599
+ function isBuiltInMarketTab(tab) {
2600
+ return "type" in tab;
2601
+ }
2602
+ function isCustomMarketTab(tab) {
2603
+ return "id" in tab;
2604
+ }
2605
+ function tabKey(tab, index) {
2606
+ return isBuiltInMarketTab(tab) ? tab.type : tab.id || `category_${index}`;
2607
+ }
2608
+ function resolveIcon(icon) {
2609
+ if (typeof icon === "string") {
2610
+ return React6.createElement("img", {
2611
+ src: icon,
2612
+ alt: "",
2613
+ style: { width: 16, height: 16 }
2614
+ });
2615
+ }
2616
+ return icon;
2617
+ }
2618
+ function resolveSuffix(suffix) {
2619
+ if (typeof suffix === "undefined" || suffix === null) {
2620
+ return void 0;
2621
+ }
2622
+ if (typeof suffix === "string") {
2623
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-ml-1 oui-inline-flex oui-items-center oui-rounded oui-bg-gradient-to-r oui-from-[rgb(var(--oui-gradient-brand-start)_/_0.12)] oui-to-[rgb(var(--oui-gradient-brand-end)_/_0.12)] oui-px-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.GradientText, { color: "brand", children: suffix }) });
2624
+ }
2625
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-ml-1", children: suffix });
2626
+ }
2627
+ function composeTabTitle(label, options) {
2628
+ const icon = options?.icon;
2629
+ const suffix = resolveSuffix(options?.suffix);
2630
+ const hasLabel = typeof label !== "undefined" && label !== null && label !== "";
2631
+ if (!hasLabel) {
2632
+ if (!icon) {
2633
+ return suffix ?? null;
2634
+ }
2635
+ return suffix ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oui-inline-flex oui-items-center oui-gap-x-1", children: [
2636
+ icon,
2637
+ suffix
2638
+ ] }) : icon;
2639
+ }
2640
+ if (icon) {
2641
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oui-inline-flex oui-items-center oui-gap-x-1", children: [
2642
+ icon,
2643
+ label,
2644
+ suffix
2645
+ ] });
2646
+ }
2647
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2648
+ label,
2649
+ suffix
2650
+ ] });
2651
+ }
2652
+ function resolveTabTriggerIcon(tab, fallbackIcon) {
2653
+ const resolvedIcon = typeof tab.icon !== "undefined" ? resolveIcon(tab.icon) : fallbackIcon;
2654
+ return React6.isValidElement(resolvedIcon) ? resolvedIcon : void 0;
2655
+ }
2656
+ function resolveTabTitle(tab, titleOverrides, rwaTitle) {
2657
+ if (isBuiltInMarketTab(tab) && tab.type === "favorites") {
2658
+ return /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {});
2659
+ }
2660
+ if (isBuiltInMarketTab(tab) && tab.type === "rwa") {
2661
+ return rwaTitle;
2662
+ }
2663
+ if (isBuiltInMarketTab(tab) && titleOverrides[tab.type]) {
2664
+ return tab.name ?? titleOverrides[tab.type];
2665
+ }
2666
+ return composeTabTitle(tab.name, {
2667
+ icon: resolveIcon(tab.icon),
2668
+ suffix: tab.suffix
2669
+ });
2670
+ }
2671
+ function useBuiltInTitles() {
2672
+ const { t } = i18n.useTranslation();
2673
+ return React6.useMemo(
2674
+ () => Object.fromEntries(
2675
+ Object.entries(BUILT_IN_TITLE_MAP).map(([key, i18nKey]) => [
2676
+ key,
2677
+ t(i18nKey)
2678
+ ])
2679
+ ),
2680
+ [t]
2681
+ );
2682
+ }
2683
+ function getCustomTabDataFilter(tab) {
2684
+ if (!tab) return void 0;
2685
+ return (data) => data.filter((item) => tab.match(item));
2686
+ }
2687
+ function useCustomTabDataFilters(tabs) {
2688
+ return React6.useMemo(() => {
2689
+ if (!tabs) return {};
2690
+ const result = {};
2691
+ tabs.forEach((tab, i) => {
2692
+ if (isCustomMarketTab(tab)) {
2693
+ result[tabKey(tab, i)] = (data) => data.filter((item) => tab.match(item));
2694
+ }
2695
+ });
2696
+ return result;
2697
+ }, [tabs]);
2698
+ }
2699
+ var BUILT_IN_TITLE_MAP;
2700
+ var init_tabUtils = __esm({
2701
+ "src/components/shared/tabUtils.tsx"() {
2702
+ init_icons();
2703
+ BUILT_IN_TITLE_MAP = {
2704
+ community: "markets.community",
2705
+ all: "common.all",
2706
+ newListing: "markets.newListings",
2707
+ recent: "markets.recent"
2708
+ };
2709
+ }
2710
+ });
2638
2711
  var MobileMarketsDataList;
2639
2712
  var init_marketsDataList_mobile_ui = __esm({
2640
2713
  "src/pages/home/marketsDataList/marketsDataList.mobile.ui.tsx"() {
2714
+ init_communityBrokerTabs();
2641
2715
  init_marketsList();
2716
+ init_marketsProvider();
2642
2717
  init_rwaTab();
2643
2718
  init_searchInput();
2644
- init_column2();
2719
+ init_column();
2645
2720
  init_useFavoritesExtraProps();
2721
+ init_tabUtils();
2722
+ init_useCommunityTabs();
2646
2723
  init_icons();
2647
2724
  init_type();
2648
2725
  MobileMarketsDataList = (props) => {
2649
2726
  const { activeTab, onTabChange, tabSort, onTabSort } = props;
2650
2727
  const { t } = i18n.useTranslation();
2728
+ const { tabs } = useMarketsContext();
2729
+ const tabDataFilters = useCustomTabDataFilters(tabs);
2651
2730
  const getColumns = React6.useCallback(
2652
2731
  (favorite, isFavoriteList = false) => {
2653
2732
  return [
2654
- getSymbolColumn(favorite, isFavoriteList),
2733
+ getSymbolColumn(favorite, isFavoriteList, {
2734
+ stackLeverageInSecondRow: true
2735
+ }),
2655
2736
  get24hVolOIColumn(),
2656
- getLastAnd24hPercentageColumn(favorite, isFavoriteList),
2657
- getMarkIndexColumn()
2737
+ getLastAnd24hPercentageColumn(favorite, isFavoriteList)
2658
2738
  ];
2659
2739
  },
2660
2740
  []
2661
2741
  );
2662
2742
  const { getFavoritesProps } = useFavoritesProps();
2743
+ const builtInMeta = React6.useMemo(
2744
+ () => ({
2745
+ favorites: {
2746
+ title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
2747
+ value: "favorites",
2748
+ tabName: "favorites" /* Favorites */
2749
+ },
2750
+ community: {
2751
+ title: t("markets.community"),
2752
+ value: "community"
2753
+ },
2754
+ all: {
2755
+ title: t("markets.allMarkets"),
2756
+ icon: /* @__PURE__ */ jsxRuntime.jsx(AllMarketsIcon, {}),
2757
+ value: "all",
2758
+ tabName: "all" /* All */
2759
+ },
2760
+ rwa: {
2761
+ title: /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {}),
2762
+ value: "rwa",
2763
+ tabName: "rwa" /* Rwa */
2764
+ },
2765
+ newListing: {
2766
+ title: t("markets.newListings"),
2767
+ icon: /* @__PURE__ */ jsxRuntime.jsx(NewListingsIcon, {}),
2768
+ value: "new",
2769
+ tabName: "newListing" /* NewListing */
2770
+ }
2771
+ }),
2772
+ [t]
2773
+ );
2663
2774
  const renderTab = (type) => {
2664
2775
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2665
2776
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2686,7 +2797,20 @@ var init_marketsDataList_mobile_ui = __esm({
2686
2797
  )
2687
2798
  ] });
2688
2799
  };
2689
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { id: "oui-markets-list", intensity: 900, py: 3, mt: 2, r: "2xl", children: /* @__PURE__ */ jsxRuntime.jsxs(
2800
+ const renderCommunityList = (selected) => {
2801
+ return /* @__PURE__ */ jsxRuntime.jsx(
2802
+ exports.MarketsListWidget,
2803
+ {
2804
+ type: "all" /* All */,
2805
+ initialSort: tabSort["community" /* Community */],
2806
+ onSort: onTabSort("community" /* Community */),
2807
+ getColumns,
2808
+ rowClassName: "!oui-h-[34px]",
2809
+ dataFilter: createCommunityBrokerFilter(selected)
2810
+ }
2811
+ );
2812
+ };
2813
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { id: "oui-markets-list", intensity: 900, py: 3, mt: 2, r: "2xl", children: /* @__PURE__ */ jsxRuntime.jsx(
2690
2814
  ui.Tabs,
2691
2815
  {
2692
2816
  variant: "contained",
@@ -2697,28 +2821,85 @@ var init_marketsDataList_mobile_ui = __esm({
2697
2821
  scrollIndicator: "oui-mx-3"
2698
2822
  },
2699
2823
  showScrollIndicator: true,
2700
- children: [
2701
- /* @__PURE__ */ jsxRuntime.jsx(ui.TabPanel, { title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}), value: "favorites", children: renderTab("favorites" /* Favorites */) }),
2702
- /* @__PURE__ */ jsxRuntime.jsx(
2703
- ui.TabPanel,
2704
- {
2705
- title: t("markets.allMarkets"),
2706
- icon: /* @__PURE__ */ jsxRuntime.jsx(AllMarketsIcon, {}),
2707
- value: "all",
2708
- children: renderTab("all" /* All */)
2709
- }
2710
- ),
2711
- /* @__PURE__ */ jsxRuntime.jsx(ui.TabPanel, { title: /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {}), value: "rwa", children: renderTab("rwa" /* Rwa */) }),
2712
- /* @__PURE__ */ jsxRuntime.jsx(
2824
+ children: tabs?.map((tab, index) => {
2825
+ const key = tabKey(tab, index);
2826
+ const isBuiltIn = isBuiltInMarketTab(tab);
2827
+ const meta = isBuiltIn ? builtInMeta[tab.type] : void 0;
2828
+ if (isBuiltIn && meta) {
2829
+ const title = tab.type === "favorites" ? composeTabTitle(tab.name, {
2830
+ icon: resolveTabTriggerIcon(tab, /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {})),
2831
+ suffix: tab.suffix
2832
+ }) : tab.type === "rwa" ? resolveTabTitle(tab, {}, /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {})) : composeTabTitle(tab.name ?? meta.title, {
2833
+ suffix: tab.suffix
2834
+ });
2835
+ return /* @__PURE__ */ jsxRuntime.jsx(
2836
+ ui.TabPanel,
2837
+ {
2838
+ title,
2839
+ icon: tab.type === "favorites" || tab.type === "rwa" ? void 0 : resolveTabTriggerIcon(tab, meta.icon),
2840
+ value: meta.value,
2841
+ children: tab.type === "community" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2842
+ /* @__PURE__ */ jsxRuntime.jsx(
2843
+ SearchInput,
2844
+ {
2845
+ classNames: {
2846
+ root: ui.cn("oui-mx-3 oui-mb-4 oui-mt-5", "oui-mb-2")
2847
+ }
2848
+ }
2849
+ ),
2850
+ /* @__PURE__ */ jsxRuntime.jsx(
2851
+ CommunityBrokerTabs,
2852
+ {
2853
+ storageKey: "orderly_mobile_markets_datalist_community_sel_sub_tab",
2854
+ size: "md",
2855
+ classNames: {
2856
+ tabsList: "oui-px-3 oui-pt-1 oui-pb-2",
2857
+ tabsContent: "oui-h-full",
2858
+ scrollIndicator: "oui-mx-3"
2859
+ },
2860
+ className: "oui-mobileMarketsDataList-community-tabs",
2861
+ showScrollIndicator: true,
2862
+ renderPanel: renderCommunityList
2863
+ }
2864
+ )
2865
+ ] }) : renderTab(meta.tabName)
2866
+ },
2867
+ key
2868
+ );
2869
+ }
2870
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2713
2871
  ui.TabPanel,
2714
2872
  {
2715
- title: t("markets.newListings"),
2716
- icon: /* @__PURE__ */ jsxRuntime.jsx(NewListingsIcon, {}),
2717
- value: "new",
2718
- children: renderTab("newListing" /* NewListing */)
2719
- }
2720
- )
2721
- ]
2873
+ title: composeTabTitle(tab.name ?? key, {
2874
+ icon: resolveTabTriggerIcon(tab),
2875
+ suffix: tab.suffix
2876
+ }),
2877
+ value: key,
2878
+ children: [
2879
+ /* @__PURE__ */ jsxRuntime.jsx(
2880
+ SearchInput,
2881
+ {
2882
+ classNames: {
2883
+ root: ui.cn("oui-mx-3 oui-mb-4 oui-mt-5", "oui-mb-2")
2884
+ }
2885
+ }
2886
+ ),
2887
+ /* @__PURE__ */ jsxRuntime.jsx(
2888
+ exports.MarketsListWidget,
2889
+ {
2890
+ type: "all" /* All */,
2891
+ dataFilter: (data) => tabDataFilters[key]?.(data) ?? data,
2892
+ initialSort: tabSort[key],
2893
+ onSort: onTabSort(key),
2894
+ getColumns,
2895
+ rowClassName: "!oui-h-[34px]"
2896
+ }
2897
+ )
2898
+ ]
2899
+ },
2900
+ key
2901
+ );
2902
+ })
2722
2903
  }
2723
2904
  ) });
2724
2905
  };
@@ -2843,26 +3024,6 @@ var init_column3 = __esm({
2843
3024
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, currency: "$", children: value });
2844
3025
  }
2845
3026
  },
2846
- {
2847
- title: t("markets.column.mark"),
2848
- dataIndex: "mark_price",
2849
- width: 100,
2850
- align: "right",
2851
- onSort: true,
2852
- render: (value, record) => {
2853
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, currency: "$", children: value });
2854
- }
2855
- },
2856
- {
2857
- title: t("markets.column.index"),
2858
- dataIndex: "index_price",
2859
- width: 100,
2860
- align: "right",
2861
- onSort: true,
2862
- render: (value, record) => {
2863
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: record.quote_dp || 2, currency: "$", children: value });
2864
- }
2865
- },
2866
3027
  {
2867
3028
  title: t("markets.column.24hChange"),
2868
3029
  dataIndex: "change",
@@ -3153,7 +3314,7 @@ var init_marketsListFull_script = __esm({
3153
3314
  rwa: hooks.MarketsType.RWA
3154
3315
  };
3155
3316
  exports.useMarketsListFullScript = (options) => {
3156
- const { type = "all" } = options;
3317
+ const { type = "all", dataFilter } = options;
3157
3318
  const [loading, setLoading] = React6.useState(true);
3158
3319
  const { setPage, pagination } = ui.usePagination({
3159
3320
  pageSize: 100
@@ -3162,9 +3323,10 @@ var init_marketsListFull_script = __esm({
3162
3323
  const { searchValue } = useMarketsContext();
3163
3324
  const { onSort, getSortedList, sort } = useSort(options.initialSort);
3164
3325
  const dataSource = React6.useMemo(() => {
3165
- const searchList = searchBySymbol(data, searchValue, "base-type");
3326
+ const filtered = typeof dataFilter === "function" ? dataFilter(data) : data;
3327
+ const searchList = searchBySymbol(filtered, searchValue, "base-type");
3166
3328
  return getSortedList(searchList);
3167
- }, [data, getSortedList, searchValue]);
3329
+ }, [data, dataFilter, getSortedList, searchValue]);
3168
3330
  React6.useEffect(() => {
3169
3331
  setLoading(false);
3170
3332
  }, [data]);
@@ -3220,11 +3382,15 @@ var init_marketsListFull = __esm({
3220
3382
  init_marketsListFull_widget();
3221
3383
  }
3222
3384
  });
3223
- var LazySearchInput, LazyFavoritesListFullWidget, LazyMarketsListFullWidget; exports.MarketsDataList = void 0;
3385
+ var LazySearchInput, LazyFavoritesListFullWidget, LazyMarketsListFullWidget, DEFAULT_SORT; exports.MarketsDataList = void 0;
3224
3386
  var init_marketsDataList_ui = __esm({
3225
3387
  "src/pages/home/marketsDataList/marketsDataList.ui.tsx"() {
3388
+ init_communityBrokerTabs();
3226
3389
  init_favoritesEmpty();
3390
+ init_marketsProvider();
3227
3391
  init_rwaTab();
3392
+ init_tabUtils();
3393
+ init_useCommunityTabs();
3228
3394
  init_icons();
3229
3395
  init_type();
3230
3396
  LazySearchInput = React6__default.default.lazy(
@@ -3242,10 +3408,53 @@ var init_marketsDataList_ui = __esm({
3242
3408
  return { default: mod.MarketsListFullWidget };
3243
3409
  })
3244
3410
  );
3411
+ DEFAULT_SORT = { sortKey: "24h_amount", sortOrder: "desc" };
3245
3412
  exports.MarketsDataList = (props) => {
3246
3413
  const { searchValue, activeTab, onTabChange } = props;
3247
3414
  const { t } = i18n.useTranslation();
3248
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { id: "oui-markets-list", intensity: 900, p: 6, r: "2xl", children: /* @__PURE__ */ jsxRuntime.jsxs(
3415
+ const { tabs } = useMarketsContext();
3416
+ const tabDataFilters = useCustomTabDataFilters(tabs);
3417
+ const builtInMeta = React6.useMemo(
3418
+ () => ({
3419
+ favorites: {
3420
+ title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
3421
+ value: "favorites",
3422
+ testid: "oui-testid-markets-favorites-tab",
3423
+ initialSort: DEFAULT_SORT
3424
+ },
3425
+ community: {
3426
+ title: t("markets.community"),
3427
+ value: "community",
3428
+ testid: "oui-testid-markets-community-tab",
3429
+ initialSort: DEFAULT_SORT
3430
+ },
3431
+ all: {
3432
+ title: t("markets.allMarkets"),
3433
+ icon: /* @__PURE__ */ jsxRuntime.jsx(AllMarketsIcon, {}),
3434
+ value: "all",
3435
+ testid: "oui-testid-markets-all-tab",
3436
+ listType: "all",
3437
+ initialSort: DEFAULT_SORT
3438
+ },
3439
+ rwa: {
3440
+ title: /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {}),
3441
+ value: "rwa",
3442
+ testid: "oui-testid-markets-rwa-tab",
3443
+ listType: "rwa",
3444
+ initialSort: DEFAULT_SORT
3445
+ },
3446
+ newListing: {
3447
+ title: t("markets.newListings"),
3448
+ icon: /* @__PURE__ */ jsxRuntime.jsx(NewListingsIcon, {}),
3449
+ value: "new",
3450
+ testid: "oui-testid-markets-newListing-tab",
3451
+ listType: "new",
3452
+ initialSort: { sortKey: "created_time", sortOrder: "desc" }
3453
+ }
3454
+ }),
3455
+ [t]
3456
+ );
3457
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { id: "oui-markets-list", intensity: 900, p: 6, r: "2xl", children: /* @__PURE__ */ jsxRuntime.jsx(
3249
3458
  ui.Tabs,
3250
3459
  {
3251
3460
  variant: "contained",
@@ -3255,93 +3464,98 @@ var init_marketsDataList_ui = __esm({
3255
3464
  trailing: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(LazySearchInput, { classNames: { root: "oui-my-1 oui-w-[240px]" } }) }),
3256
3465
  classNames: {
3257
3466
  tabsList: "oui-tabs-markets-list",
3258
- tabsContent: "oui-tabs-markets-content"
3467
+ tabsContent: "oui-tabs-markets-content",
3468
+ scrollIndicator: "oui-mr-3"
3259
3469
  },
3260
3470
  className: "oui-markets-list-tabs",
3261
- children: [
3262
- /* @__PURE__ */ jsxRuntime.jsx(
3263
- ui.TabPanel,
3264
- {
3265
- classNames: {
3266
- trigger: "oui-tabs-favorites-trigger",
3267
- content: "oui-tabs-favorites-content"
3268
- },
3269
- title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
3270
- value: "favorites",
3271
- testid: "oui-testid-markets-favorites-tab",
3272
- children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3273
- LazyFavoritesListFullWidget,
3274
- {
3275
- emptyView: !searchValue && /* @__PURE__ */ jsxRuntime.jsx(
3276
- FavoritesEmpty,
3277
- {
3278
- onClick: () => onTabChange("all" /* All */)
3279
- }
3280
- )
3281
- }
3282
- ) })
3283
- }
3284
- ),
3285
- /* @__PURE__ */ jsxRuntime.jsx(
3286
- ui.TabPanel,
3287
- {
3288
- classNames: {
3289
- trigger: "oui-tabs-all-trigger",
3290
- content: "oui-tabs-all-content"
3291
- },
3292
- title: t("markets.allMarkets"),
3293
- icon: /* @__PURE__ */ jsxRuntime.jsx(AllMarketsIcon, {}),
3294
- value: "all",
3295
- testid: "oui-testid-markets-all-tab",
3296
- children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3297
- LazyMarketsListFullWidget,
3298
- {
3299
- type: "all",
3300
- initialSort: { sortKey: "24h_amount", sortOrder: "desc" }
3301
- }
3302
- ) })
3303
- }
3304
- ),
3305
- /* @__PURE__ */ jsxRuntime.jsx(
3306
- ui.TabPanel,
3307
- {
3308
- classNames: {
3309
- trigger: "oui-tabs-rwa-trigger",
3310
- content: "oui-tabs-rwa-content"
3471
+ showScrollIndicator: true,
3472
+ children: tabs?.map((tab, index) => {
3473
+ const key = tabKey(tab, index);
3474
+ const isBuiltIn = isBuiltInMarketTab(tab);
3475
+ const meta = isBuiltIn ? builtInMeta[tab.type] : void 0;
3476
+ if (isBuiltIn && meta) {
3477
+ const title = tab.type === "favorites" ? composeTabTitle(tab.name, {
3478
+ icon: resolveTabTriggerIcon(tab, /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {})),
3479
+ suffix: tab.suffix
3480
+ }) : tab.type === "rwa" ? resolveTabTitle(tab, {}, /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {})) : composeTabTitle(tab.name ?? meta.title, {
3481
+ suffix: tab.suffix
3482
+ });
3483
+ return /* @__PURE__ */ jsxRuntime.jsx(
3484
+ ui.TabPanel,
3485
+ {
3486
+ classNames: {
3487
+ trigger: `oui-tabs-${meta.value}-trigger`,
3488
+ content: `oui-tabs-${meta.value}-content`
3489
+ },
3490
+ title,
3491
+ icon: tab.type === "favorites" || tab.type === "rwa" ? void 0 : resolveTabTriggerIcon(tab, meta.icon),
3492
+ value: meta.value,
3493
+ testid: meta.testid,
3494
+ children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: tab.type === "favorites" ? /* @__PURE__ */ jsxRuntime.jsx(
3495
+ LazyFavoritesListFullWidget,
3496
+ {
3497
+ emptyView: !searchValue && /* @__PURE__ */ jsxRuntime.jsx(
3498
+ FavoritesEmpty,
3499
+ {
3500
+ onClick: () => onTabChange("all" /* All */)
3501
+ }
3502
+ )
3503
+ }
3504
+ ) : tab.type === "community" ? /* @__PURE__ */ jsxRuntime.jsx(
3505
+ CommunityBrokerTabs,
3506
+ {
3507
+ storageKey: "orderly_markets_datalist_community_sel_sub_tab",
3508
+ size: "md",
3509
+ classNames: {
3510
+ tabsList: "oui-px-3 oui-pt-1 oui-pb-2",
3511
+ tabsContent: "oui-h-full"
3512
+ },
3513
+ className: "oui-marketsDataList-community-tabs",
3514
+ showScrollIndicator: true,
3515
+ renderPanel: (selected) => /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3516
+ LazyMarketsListFullWidget,
3517
+ {
3518
+ type: "all",
3519
+ initialSort: meta.initialSort,
3520
+ dataFilter: createCommunityBrokerFilter(selected)
3521
+ }
3522
+ ) })
3523
+ }
3524
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3525
+ LazyMarketsListFullWidget,
3526
+ {
3527
+ type: meta.listType,
3528
+ initialSort: meta.initialSort
3529
+ }
3530
+ ) })
3311
3531
  },
3312
- title: /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {}),
3313
- value: "rwa",
3314
- testid: "oui-testid-markets-rwa-tab",
3315
- children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3316
- LazyMarketsListFullWidget,
3317
- {
3318
- type: "rwa",
3319
- initialSort: { sortKey: "24h_amount", sortOrder: "desc" }
3320
- }
3321
- ) })
3322
- }
3323
- ),
3324
- /* @__PURE__ */ jsxRuntime.jsx(
3532
+ key
3533
+ );
3534
+ }
3535
+ return /* @__PURE__ */ jsxRuntime.jsx(
3325
3536
  ui.TabPanel,
3326
3537
  {
3327
3538
  classNames: {
3328
- trigger: "oui-tabs-newListings-trigger",
3329
- content: "oui-tabs-newListings-content"
3539
+ trigger: `oui-tabs-${key}-trigger`,
3540
+ content: `oui-tabs-${key}-content`
3330
3541
  },
3331
- title: t("markets.newListings"),
3332
- icon: /* @__PURE__ */ jsxRuntime.jsx(NewListingsIcon, {}),
3333
- value: "new",
3334
- testid: "oui-testid-markets-newListings-tab",
3542
+ title: composeTabTitle(tab.name ?? key, {
3543
+ icon: resolveTabTriggerIcon(tab),
3544
+ suffix: tab.suffix
3545
+ }),
3546
+ value: key,
3335
3547
  children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3336
3548
  LazyMarketsListFullWidget,
3337
3549
  {
3338
- type: "new",
3339
- initialSort: { sortKey: "created_time", sortOrder: "desc" }
3550
+ type: "all",
3551
+ initialSort: DEFAULT_SORT,
3552
+ dataFilter: tabDataFilters[key]
3340
3553
  }
3341
3554
  ) })
3342
- }
3343
- )
3344
- ]
3555
+ },
3556
+ key
3557
+ );
3558
+ })
3345
3559
  }
3346
3560
  ) });
3347
3561
  };
@@ -3378,10 +3592,13 @@ var init_marketsDataList = __esm({
3378
3592
  var LazySearchInput2, LazyMarketsListWidget, cls; exports.ExpandMarkets = void 0;
3379
3593
  var init_expandMarkets_ui = __esm({
3380
3594
  "src/components/expandMarkets/expandMarkets.ui.tsx"() {
3381
- init_icons();
3595
+ init_useCommunityTabs();
3382
3596
  init_type();
3597
+ init_communityBrokerTabs();
3598
+ init_marketsProvider();
3383
3599
  init_rwaTab();
3384
3600
  init_useFavoritesExtraProps();
3601
+ init_tabUtils();
3385
3602
  LazySearchInput2 = React6__default.default.lazy(
3386
3603
  () => Promise.resolve().then(() => (init_searchInput(), searchInput_exports)).then((mod) => {
3387
3604
  return { default: mod.SearchInput };
@@ -3392,28 +3609,31 @@ var init_expandMarkets_ui = __esm({
3392
3609
  return { default: mod.MarketsListWidget };
3393
3610
  })
3394
3611
  );
3395
- cls = "oui-h-[calc(100%_-_36px)]";
3612
+ cls = "oui-h-full";
3396
3613
  exports.ExpandMarkets = (props) => {
3397
3614
  const { activeTab, onTabChange, tabSort, onTabSort } = props;
3398
- const { t } = i18n.useTranslation();
3399
3615
  const { getFavoritesProps, renderEmptyView } = useFavoritesProps();
3400
- const renderTab = (type) => {
3616
+ const builtInTitles = useBuiltInTitles();
3617
+ const { tabs } = useMarketsContext();
3618
+ const tabDataFilters = useCustomTabDataFilters(tabs);
3619
+ const renderBuiltInContent = (type) => {
3620
+ const tabType = type;
3401
3621
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3402
3622
  LazyMarketsListWidget,
3403
3623
  {
3404
- type,
3624
+ type: tabType,
3405
3625
  initialSort: tabSort[type],
3406
- onSort: onTabSort(type),
3626
+ onSort: onTabSort(tabType),
3407
3627
  tableClassNames: {
3408
3628
  root: "oui-expandMarkets-list",
3409
3629
  scroll: ui.cn(
3410
3630
  "oui-px-1",
3411
- type === "favorites" /* Favorites */ ? "oui-pb-9" : "oui-pb-2"
3631
+ tabType === "favorites" /* Favorites */ ? "oui-pb-9" : "oui-pb-2"
3412
3632
  )
3413
3633
  },
3414
- ...getFavoritesProps(type),
3634
+ ...getFavoritesProps(tabType),
3415
3635
  emptyView: renderEmptyView({
3416
- type,
3636
+ type: tabType,
3417
3637
  onClick: () => {
3418
3638
  onTabChange("all" /* All */);
3419
3639
  }
@@ -3421,6 +3641,48 @@ var init_expandMarkets_ui = __esm({
3421
3641
  }
3422
3642
  ) }) });
3423
3643
  };
3644
+ const renderCommunityContent = () => {
3645
+ return /* @__PURE__ */ jsxRuntime.jsx(
3646
+ CommunityBrokerTabs,
3647
+ {
3648
+ storageKey: "orderly_expand_markets_community_sel_sub_tab",
3649
+ classNames: {
3650
+ tabsList: "oui-px-3 oui-pt-1 oui-pb-2",
3651
+ tabsContent: "oui-h-full"
3652
+ },
3653
+ className: ui.cn("oui-expandMarkets-community-tabs", cls),
3654
+ showScrollIndicator: true,
3655
+ renderPanel: (selected) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3656
+ LazyMarketsListWidget,
3657
+ {
3658
+ type: "all" /* All */,
3659
+ initialSort: tabSort["community" /* Community */],
3660
+ onSort: onTabSort("community" /* Community */),
3661
+ tableClassNames: {
3662
+ root: "oui-expandMarkets-list",
3663
+ scroll: ui.cn("oui-px-1", "oui-pb-2")
3664
+ },
3665
+ dataFilter: createCommunityBrokerFilter(selected)
3666
+ }
3667
+ ) }) })
3668
+ }
3669
+ );
3670
+ };
3671
+ const renderCustomContent = (key) => {
3672
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
3673
+ LazyMarketsListWidget,
3674
+ {
3675
+ type: "all" /* All */,
3676
+ dataFilter: (data) => tabDataFilters[key]?.(data) ?? data,
3677
+ initialSort: tabSort[key],
3678
+ onSort: onTabSort(key),
3679
+ tableClassNames: {
3680
+ root: "oui-expandMarkets-list",
3681
+ scroll: ui.cn("oui-px-1", "oui-pb-2")
3682
+ }
3683
+ }
3684
+ ) }) });
3685
+ };
3424
3686
  return /* @__PURE__ */ jsxRuntime.jsxs(
3425
3687
  ui.Box,
3426
3688
  {
@@ -3436,7 +3698,7 @@ var init_expandMarkets_ui = __esm({
3436
3698
  classNames: { root: "oui-expandMarkets-search-input" }
3437
3699
  }
3438
3700
  ) }) }),
3439
- /* @__PURE__ */ jsxRuntime.jsxs(
3701
+ /* @__PURE__ */ jsxRuntime.jsx(
3440
3702
  ui.Tabs,
3441
3703
  {
3442
3704
  variant: "contained",
@@ -3450,68 +3712,24 @@ var init_expandMarkets_ui = __esm({
3450
3712
  },
3451
3713
  className: ui.cn("oui-expandMarkets-tabs", cls),
3452
3714
  showScrollIndicator: true,
3453
- children: [
3454
- /* @__PURE__ */ jsxRuntime.jsx(
3455
- ui.TabPanel,
3456
- {
3457
- classNames: {
3458
- trigger: "oui-tabs-favorites-trigger",
3459
- content: "oui-tabs-favorites-content"
3460
- },
3461
- title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
3462
- value: "favorites" /* Favorites */,
3463
- children: renderTab("favorites" /* Favorites */)
3464
- }
3465
- ),
3466
- /* @__PURE__ */ jsxRuntime.jsx(
3467
- ui.TabPanel,
3468
- {
3469
- classNames: {
3470
- trigger: "oui-tabs-all-trigger",
3471
- content: "oui-tabs-all-content"
3472
- },
3473
- title: t("common.all"),
3474
- value: "all" /* All */,
3475
- children: renderTab("all" /* All */)
3476
- }
3477
- ),
3478
- /* @__PURE__ */ jsxRuntime.jsx(
3479
- ui.TabPanel,
3480
- {
3481
- classNames: {
3482
- trigger: "oui-tabs-rwa-trigger",
3483
- content: "oui-tabs-rwa-content"
3484
- },
3485
- title: /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {}),
3486
- value: "rwa" /* Rwa */,
3487
- children: renderTab("rwa" /* Rwa */)
3488
- }
3489
- ),
3490
- /* @__PURE__ */ jsxRuntime.jsx(
3491
- ui.TabPanel,
3492
- {
3493
- classNames: {
3494
- trigger: "oui-tabs-newListings-trigger",
3495
- content: "oui-tabs-newListings-content"
3496
- },
3497
- title: t("markets.newListings"),
3498
- value: "newListing" /* NewListing */,
3499
- children: renderTab("newListing" /* NewListing */)
3500
- }
3501
- ),
3502
- /* @__PURE__ */ jsxRuntime.jsx(
3715
+ children: tabs?.map((tab, index) => {
3716
+ const key = tabKey(tab, index);
3717
+ const isBuiltIn = isBuiltInMarketTab(tab);
3718
+ const isCommunity = isBuiltIn && tab.type === "community" /* Community */;
3719
+ return /* @__PURE__ */ jsxRuntime.jsx(
3503
3720
  ui.TabPanel,
3504
3721
  {
3505
3722
  classNames: {
3506
- trigger: "oui-tabs-recent-trigger",
3507
- content: "oui-tabs-recent-content"
3723
+ trigger: `oui-tabs-${key}-trigger`,
3724
+ content: `oui-tabs-${key}-content`
3508
3725
  },
3509
- title: t("markets.recent"),
3510
- value: "recent" /* Recent */,
3511
- children: renderTab("recent" /* Recent */)
3512
- }
3513
- )
3514
- ]
3726
+ title: resolveTabTitle(tab, builtInTitles, /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {})),
3727
+ value: key,
3728
+ children: isCommunity ? renderCommunityContent() : isBuiltIn ? renderBuiltInContent(tab.type) : renderCustomContent(key)
3729
+ },
3730
+ key
3731
+ );
3732
+ })
3515
3733
  }
3516
3734
  )
3517
3735
  ]
@@ -3568,10 +3786,94 @@ var init_expandMarkets_script = __esm({
3568
3786
  init_useTabSort();
3569
3787
  }
3570
3788
  });
3789
+
3790
+ // src/registry/builtInTabRegistry.ts
3791
+ exports.builtInTabs = void 0; var componentDefaultTabs;
3792
+ var init_builtInTabRegistry = __esm({
3793
+ "src/registry/builtInTabRegistry.ts"() {
3794
+ exports.builtInTabs = {
3795
+ favorites: { type: "favorites" },
3796
+ community: {
3797
+ type: "community",
3798
+ isVisible: (symbolList) => {
3799
+ return symbolList.some((m) => Boolean(m?.broker_id));
3800
+ }
3801
+ },
3802
+ all: { type: "all" },
3803
+ rwa: { type: "rwa" },
3804
+ newListing: { type: "newListing" },
3805
+ recent: { type: "recent" }
3806
+ };
3807
+ componentDefaultTabs = {
3808
+ marketsSheet: [
3809
+ { type: "favorites" },
3810
+ { type: "all" },
3811
+ { type: "rwa" },
3812
+ { ...exports.builtInTabs.community }
3813
+ ],
3814
+ expandMarkets: [
3815
+ { type: "favorites" },
3816
+ { type: "all" },
3817
+ { type: "rwa" },
3818
+ { ...exports.builtInTabs.community },
3819
+ { type: "newListing" },
3820
+ { type: "recent" }
3821
+ ],
3822
+ dropDownMarkets: [
3823
+ { type: "favorites" },
3824
+ { type: "all" },
3825
+ { type: "rwa" },
3826
+ { ...exports.builtInTabs.community },
3827
+ { type: "newListing" },
3828
+ { type: "recent" }
3829
+ ],
3830
+ subMenuMarkets: [
3831
+ { type: "favorites" },
3832
+ { type: "all" },
3833
+ { type: "rwa" },
3834
+ { ...exports.builtInTabs.community },
3835
+ { type: "newListing" },
3836
+ { type: "recent" }
3837
+ ],
3838
+ marketsDataList: [
3839
+ { type: "favorites" },
3840
+ { type: "all" },
3841
+ { type: "rwa" },
3842
+ { ...exports.builtInTabs.community },
3843
+ { type: "newListing" }
3844
+ ],
3845
+ horizontalMarkets: [
3846
+ { type: "all" },
3847
+ { type: "recent" },
3848
+ { type: "newListing" },
3849
+ { type: "favorites" }
3850
+ ]
3851
+ };
3852
+ }
3853
+ });
3854
+ function useMarketCategories(componentKey) {
3855
+ const marketTabs = hooks.useMarketCategoriesConfig();
3856
+ const { i18n: i18n2 } = i18n.useTranslation();
3857
+ const symbolList = hooks.useMarketList();
3858
+ const rwaSymbolsInfo = hooks.useRwaSymbolsInfo();
3859
+ return React6.useMemo(() => {
3860
+ const original = componentDefaultTabs[componentKey];
3861
+ const resolved = marketTabs ? marketTabs(original, { componentKey, builtIn: exports.builtInTabs }) : original;
3862
+ return resolved.filter(
3863
+ (tab) => tab.isVisible?.(symbolList, { rwaSymbolsInfo }) ?? true
3864
+ );
3865
+ }, [marketTabs, componentKey, i18n2.language, symbolList, rwaSymbolsInfo]);
3866
+ }
3867
+ var init_useMarketCategories = __esm({
3868
+ "src/components/shared/hooks/useMarketCategories.ts"() {
3869
+ init_builtInTabRegistry();
3870
+ }
3871
+ });
3571
3872
  exports.ExpandMarketsWidget = void 0;
3572
3873
  var init_expandMarkets_widget = __esm({
3573
3874
  "src/components/expandMarkets/expandMarkets.widget.tsx"() {
3574
3875
  init_marketsProvider();
3876
+ init_useMarketCategories();
3575
3877
  init_expandMarkets_script();
3576
3878
  init_expandMarkets_ui();
3577
3879
  exports.ExpandMarketsWidget = (props) => {
@@ -3579,11 +3881,13 @@ var init_expandMarkets_widget = __esm({
3579
3881
  activeTab: props.activeTab,
3580
3882
  onTabChange: props.onTabChange
3581
3883
  });
3884
+ const tabs = useMarketCategories("expandMarkets");
3582
3885
  return /* @__PURE__ */ jsxRuntime.jsx(
3583
3886
  exports.MarketsProvider,
3584
3887
  {
3585
3888
  symbol: props.symbol,
3586
3889
  onSymbolChange: props.onSymbolChange,
3890
+ tabs,
3587
3891
  children: /* @__PURE__ */ jsxRuntime.jsx(exports.ExpandMarkets, { ...state })
3588
3892
  }
3589
3893
  );
@@ -3628,7 +3932,7 @@ var init_columns = __esm({
3628
3932
  title: t("markets.column.market"),
3629
3933
  dataIndex: "symbol",
3630
3934
  onSort: true,
3631
- width: 135,
3935
+ width: 180,
3632
3936
  className: isMobile ? "oui-pl-0" : void 0,
3633
3937
  render: (value, record) => {
3634
3938
  if (isMobile) {
@@ -4018,7 +4322,7 @@ var init_columns2 = __esm({
4018
4322
  {
4019
4323
  title: t("markets.column.market"),
4020
4324
  dataIndex: "symbol",
4021
- width: 150,
4325
+ width: 220,
4022
4326
  onSort: true,
4023
4327
  className: isMobile ? "oui-pl-0" : void 0,
4024
4328
  render: (value, record) => {
@@ -4269,53 +4573,17 @@ var init_fundingComparison = __esm({
4269
4573
  // src/components/sideMarkets/sideMarkets.ui.tsx
4270
4574
  var sideMarkets_ui_exports = {};
4271
4575
  __export(sideMarkets_ui_exports, {
4272
- SideMarkets: () => exports.SideMarkets,
4273
- SideMarketsHeader: () => SideMarketsHeader
4576
+ SideMarkets: () => exports.SideMarkets
4274
4577
  });
4275
- var SideMarketsHeader; exports.SideMarkets = void 0;
4578
+ exports.SideMarkets = void 0;
4276
4579
  var init_sideMarkets_ui = __esm({
4277
4580
  "src/components/sideMarkets/sideMarkets.ui.tsx"() {
4278
- init_icons();
4279
4581
  init_expandMarkets();
4280
4582
  init_marketsList();
4281
4583
  init_marketsProvider();
4282
4584
  init_useFavoritesExtraProps();
4283
- SideMarketsHeader = (props) => {
4284
- const { resizeable, panelSize, onPanelSizeChange } = props;
4285
- const { t } = i18n.useTranslation();
4286
- const cls3 = ui.cn(
4287
- "oui-text-base-contrast-36",
4288
- resizeable ? "oui-cursor-pointer hover:oui-text-base-contrast-80" : "oui-cursor-not-allowed"
4289
- );
4290
- return /* @__PURE__ */ jsxRuntime.jsxs(
4291
- ui.Flex,
4292
- {
4293
- className: panelSize === "small" ? "oui-absolute oui-end-[-20px] oui-z-50" : "oui-relative",
4294
- justify: panelSize === "large" ? "between" : "center",
4295
- width: "100%",
4296
- px: 3,
4297
- children: [
4298
- panelSize === "large" && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "base", intensity: 80, children: t("common.markets") }),
4299
- panelSize === "large" && /* @__PURE__ */ jsxRuntime.jsx(
4300
- "div",
4301
- {
4302
- onClick: resizeable ? () => onPanelSizeChange?.("middle") : void 0,
4303
- children: /* @__PURE__ */ jsxRuntime.jsx(CollapseIcon, { className: cls3 })
4304
- }
4305
- ),
4306
- (panelSize === "middle" || panelSize === "small") && /* @__PURE__ */ jsxRuntime.jsx(
4307
- "div",
4308
- {
4309
- onClick: resizeable ? () => onPanelSizeChange?.("large") : void 0,
4310
- children: /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, { className: cls3 })
4311
- }
4312
- )
4313
- ]
4314
- }
4315
- );
4316
- };
4317
4585
  exports.SideMarkets = (props) => {
4318
- const { panelSize, activeTab, onTabChange, className, tabSort } = props;
4586
+ const { activeTab, onTabChange, className, tabSort, panelSize } = props;
4319
4587
  const { symbol, onSymbolChange } = useMarketsContext();
4320
4588
  const { getFavoritesProps } = useFavoritesProps();
4321
4589
  const renderContent = () => {
@@ -4340,34 +4608,12 @@ var init_sideMarkets_ui = __esm({
4340
4608
  }
4341
4609
  );
4342
4610
  };
4343
- return /* @__PURE__ */ jsxRuntime.jsxs(
4344
- ui.Flex,
4611
+ return /* @__PURE__ */ jsxRuntime.jsx(
4612
+ ui.Box,
4345
4613
  {
4346
- id: "oui-side-markets",
4347
- className: ui.cn("oui-relative oui-font-semibold", className),
4348
- direction: "column",
4349
- gapY: 5,
4350
- height: "100%",
4351
4614
  width: "100%",
4352
- children: [
4353
- /* @__PURE__ */ jsxRuntime.jsx(
4354
- SideMarketsHeader,
4355
- {
4356
- ...ramda.pick(["resizeable", "panelSize", "onPanelSizeChange"], props)
4357
- }
4358
- ),
4359
- /* @__PURE__ */ jsxRuntime.jsx(
4360
- ui.Box,
4361
- {
4362
- width: "100%",
4363
- className: ui.cn(
4364
- panelSize === "large" && "oui-h-[calc(100%_-_56px)]",
4365
- panelSize === "middle" && "oui-h-[calc(100%_-_52px)]"
4366
- ),
4367
- children: renderContent()
4368
- }
4369
- )
4370
- ]
4615
+ height: "100%",
4616
+ children: renderContent()
4371
4617
  }
4372
4618
  );
4373
4619
  };
@@ -4377,7 +4623,7 @@ exports.useDropDownMarketsColumns = void 0;
4377
4623
  var init_column4 = __esm({
4378
4624
  "src/components/dropDownMarkets/column.tsx"() {
4379
4625
  init_icons();
4380
- init_column2();
4626
+ init_column();
4381
4627
  exports.useDropDownMarketsColumns = () => {
4382
4628
  const { t } = i18n.useTranslation();
4383
4629
  return React6.useCallback(
@@ -4472,12 +4718,15 @@ var init_column4 = __esm({
4472
4718
  exports.DropDownMarkets = void 0; exports.DropDownMarketsConetnt = void 0;
4473
4719
  var init_dropDownMarkets_ui = __esm({
4474
4720
  "src/components/dropDownMarkets/dropDownMarkets.ui.tsx"() {
4475
- init_icons();
4721
+ init_useCommunityTabs();
4476
4722
  init_type();
4723
+ init_communityBrokerTabs();
4477
4724
  init_marketsList();
4725
+ init_marketsProvider();
4478
4726
  init_rwaTab();
4479
4727
  init_searchInput();
4480
4728
  init_useFavoritesExtraProps();
4729
+ init_tabUtils();
4481
4730
  init_column4();
4482
4731
  exports.DropDownMarkets = (props) => {
4483
4732
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuRoot, { open: props.open, onOpenChange: props.onOpenChange, children: [
@@ -4501,8 +4750,8 @@ var init_dropDownMarkets_ui = __esm({
4501
4750
  };
4502
4751
  exports.DropDownMarketsConetnt = (props) => {
4503
4752
  const { activeTab, onTabChange, tabSort, onTabSort } = props;
4504
- const { t } = i18n.useTranslation();
4505
4753
  const getColumns = exports.useDropDownMarketsColumns();
4754
+ const builtInTitles = useBuiltInTitles();
4506
4755
  const search = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-dropDownMarkets-search", mx: 3, gapX: 3, pt: 3, pb: 2, children: [
4507
4756
  /* @__PURE__ */ jsxRuntime.jsx(
4508
4757
  SearchInput,
@@ -4524,22 +4773,24 @@ var init_dropDownMarkets_ui = __esm({
4524
4773
  ] });
4525
4774
  const cls3 = "oui-h-[calc(100%_-_36px)]";
4526
4775
  const { getFavoritesProps, renderEmptyView } = useFavoritesProps();
4527
- const renderTab = (type) => {
4776
+ const { tabs } = useMarketsContext();
4777
+ const tabDataFilters = useCustomTabDataFilters(tabs);
4778
+ const renderBuiltInContent = (tabType) => {
4528
4779
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls3, children: /* @__PURE__ */ jsxRuntime.jsx(
4529
4780
  exports.MarketsListWidget,
4530
4781
  {
4531
- type,
4532
- initialSort: tabSort[type],
4533
- onSort: onTabSort(type),
4782
+ type: tabType,
4783
+ initialSort: tabSort[tabType],
4784
+ onSort: onTabSort(tabType),
4534
4785
  getColumns,
4535
4786
  tableClassNames: {
4536
4787
  root: ui.cn("oui-dropDownMarkets-list", "!oui-bg-base-8"),
4537
4788
  scroll: "oui-pb-5 oui-px-1"
4538
4789
  },
4539
4790
  rowClassName: "!oui-h-[34px]",
4540
- ...getFavoritesProps(type),
4791
+ ...getFavoritesProps(tabType),
4541
4792
  emptyView: renderEmptyView({
4542
- type,
4793
+ type: tabType,
4543
4794
  onClick: () => {
4544
4795
  onTabChange("all" /* All */);
4545
4796
  }
@@ -4547,6 +4798,52 @@ var init_dropDownMarkets_ui = __esm({
4547
4798
  }
4548
4799
  ) });
4549
4800
  };
4801
+ const renderCommunityContent = () => {
4802
+ return /* @__PURE__ */ jsxRuntime.jsx(
4803
+ CommunityBrokerTabs,
4804
+ {
4805
+ storageKey: "orderly_dropdown_markets_community_sel_sub_tab",
4806
+ classNames: {
4807
+ tabsList: "oui-px-3 oui-pt-1 oui-pb-2",
4808
+ tabsContent: "oui-h-full"
4809
+ },
4810
+ className: ui.cn("oui-dropDownMarkets-community-tabs", cls3),
4811
+ showScrollIndicator: true,
4812
+ renderPanel: (selected) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls3, children: /* @__PURE__ */ jsxRuntime.jsx(
4813
+ exports.MarketsListWidget,
4814
+ {
4815
+ type: "all" /* All */,
4816
+ initialSort: tabSort["community" /* Community */],
4817
+ onSort: onTabSort("community" /* Community */),
4818
+ getColumns,
4819
+ tableClassNames: {
4820
+ root: ui.cn("oui-dropDownMarkets-list", "!oui-bg-base-8"),
4821
+ scroll: "oui-pb-5 oui-px-1"
4822
+ },
4823
+ rowClassName: "!oui-h-[34px]",
4824
+ dataFilter: createCommunityBrokerFilter(selected)
4825
+ }
4826
+ ) })
4827
+ }
4828
+ );
4829
+ };
4830
+ const renderCustomContent = (key) => {
4831
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls3, children: /* @__PURE__ */ jsxRuntime.jsx(
4832
+ exports.MarketsListWidget,
4833
+ {
4834
+ type: "all" /* All */,
4835
+ dataFilter: (data) => tabDataFilters[key]?.(data) ?? data,
4836
+ initialSort: tabSort[key],
4837
+ onSort: onTabSort(key),
4838
+ getColumns,
4839
+ tableClassNames: {
4840
+ root: ui.cn("oui-dropDownMarkets-list", "!oui-bg-base-8"),
4841
+ scroll: "oui-pb-5 oui-px-1"
4842
+ },
4843
+ rowClassName: "!oui-h-[34px]"
4844
+ }
4845
+ ) });
4846
+ };
4550
4847
  return /* @__PURE__ */ jsxRuntime.jsxs(
4551
4848
  ui.Box,
4552
4849
  {
@@ -4558,7 +4855,7 @@ var init_dropDownMarkets_ui = __esm({
4558
4855
  intensity: 800,
4559
4856
  children: [
4560
4857
  search,
4561
- /* @__PURE__ */ jsxRuntime.jsxs(
4858
+ /* @__PURE__ */ jsxRuntime.jsx(
4562
4859
  ui.Tabs,
4563
4860
  {
4564
4861
  variant: "contained",
@@ -4566,72 +4863,31 @@ var init_dropDownMarkets_ui = __esm({
4566
4863
  value: activeTab,
4567
4864
  onValueChange: onTabChange,
4568
4865
  classNames: {
4569
- tabsList: "oui-my-[6px] oui-px-3",
4570
- tabsContent: "oui-h-full"
4866
+ tabsListContainer: "oui-px-3",
4867
+ tabsList: "oui-my-[6px]",
4868
+ tabsContent: "oui-h-full",
4869
+ scrollIndicator: "oui-mx-0"
4571
4870
  },
4572
4871
  className: ui.cn("oui-dropDownMarkets-tabs", cls3),
4573
- children: [
4574
- /* @__PURE__ */ jsxRuntime.jsx(
4575
- ui.TabPanel,
4576
- {
4577
- classNames: {
4578
- trigger: "oui-tabs-favorites-trigger",
4579
- content: "oui-tabs-favorites-content"
4580
- },
4581
- title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
4582
- value: "favorites" /* Favorites */,
4583
- children: renderTab("favorites" /* Favorites */)
4584
- }
4585
- ),
4586
- /* @__PURE__ */ jsxRuntime.jsx(
4587
- ui.TabPanel,
4588
- {
4589
- classNames: {
4590
- trigger: "oui-tabs-all-trigger",
4591
- content: "oui-tabs-all-content"
4592
- },
4593
- title: t("common.all"),
4594
- value: "all" /* All */,
4595
- children: renderTab("all" /* All */)
4596
- }
4597
- ),
4598
- /* @__PURE__ */ jsxRuntime.jsx(
4599
- ui.TabPanel,
4600
- {
4601
- classNames: {
4602
- trigger: "oui-tabs-rwa-trigger",
4603
- content: "oui-tabs-rwa-content"
4604
- },
4605
- title: /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {}),
4606
- value: "rwa" /* Rwa */,
4607
- children: renderTab("rwa" /* Rwa */)
4608
- }
4609
- ),
4610
- /* @__PURE__ */ jsxRuntime.jsx(
4611
- ui.TabPanel,
4612
- {
4613
- classNames: {
4614
- trigger: "oui-tabs-newListings-trigger",
4615
- content: "oui-tabs-newListings-content"
4616
- },
4617
- title: t("markets.newListings"),
4618
- value: "newListing" /* NewListing */,
4619
- children: renderTab("newListing" /* NewListing */)
4620
- }
4621
- ),
4622
- /* @__PURE__ */ jsxRuntime.jsx(
4872
+ showScrollIndicator: true,
4873
+ children: tabs?.map((tab, index) => {
4874
+ const key = tabKey(tab, index);
4875
+ const isBuiltIn = isBuiltInMarketTab(tab);
4876
+ const isCommunity = isBuiltIn && tab.type === "community" /* Community */;
4877
+ return /* @__PURE__ */ jsxRuntime.jsx(
4623
4878
  ui.TabPanel,
4624
4879
  {
4625
4880
  classNames: {
4626
- trigger: "oui-tabs-recent-trigger",
4627
- content: "oui-tabs-recent-content"
4881
+ trigger: `oui-tabs-${key}-trigger`,
4882
+ content: `oui-tabs-${key}-content`
4628
4883
  },
4629
- title: t("markets.recent"),
4630
- value: "recent" /* Recent */,
4631
- children: renderTab("recent" /* Recent */)
4632
- }
4633
- )
4634
- ]
4884
+ title: resolveTabTitle(tab, builtInTitles, /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {})),
4885
+ value: key,
4886
+ children: isCommunity ? renderCommunityContent() : isBuiltIn ? renderBuiltInContent(tab.type) : renderCustomContent(key)
4887
+ },
4888
+ key
4889
+ );
4890
+ })
4635
4891
  }
4636
4892
  )
4637
4893
  ]
@@ -4680,15 +4936,18 @@ exports.DropDownMarketsWidget = void 0;
4680
4936
  var init_dropDownMarkets_widget = __esm({
4681
4937
  "src/components/dropDownMarkets/dropDownMarkets.widget.tsx"() {
4682
4938
  init_marketsProvider();
4939
+ init_useMarketCategories();
4683
4940
  init_dropDownMarkets_script();
4684
4941
  init_dropDownMarkets_ui();
4685
4942
  exports.DropDownMarketsWidget = (props) => {
4686
4943
  const state = useDropDownMarketsScript();
4944
+ const tabs = useMarketCategories("dropDownMarkets");
4687
4945
  return /* @__PURE__ */ jsxRuntime.jsx(
4688
4946
  exports.MarketsProvider,
4689
4947
  {
4690
4948
  symbol: props.symbol,
4691
4949
  onSymbolChange: props.onSymbolChange,
4950
+ tabs,
4692
4951
  children: /* @__PURE__ */ jsxRuntime.jsx(exports.DropDownMarkets, { ...state, contentClassName: props.contentClassName, children: props.children })
4693
4952
  }
4694
4953
  );
@@ -4829,26 +5088,47 @@ var init_marketItem_ui = __esm({
4829
5088
  exports.MarketItem.displayName = "MarketItem";
4830
5089
  }
4831
5090
  });
4832
- var marketTypeBase; exports.MarketTypeFilter = void 0;
5091
+ exports.MarketTypeFilter = void 0;
4833
5092
  var init_marketTypeFilter_ui = __esm({
4834
5093
  "src/components/horizontalMarkets/marketTypeFilter.ui.tsx"() {
4835
5094
  init_icons();
4836
- marketTypeBase = [
4837
- { value: "recent", label: "Recent", translationKey: "Recent" },
4838
- { value: "all", label: "All Markets", translationKey: "All" },
4839
- { value: "newListing", label: "New Listing", translationKey: "New listing" }
4840
- ];
5095
+ init_tabUtils();
4841
5096
  exports.MarketTypeFilter = (props) => {
4842
5097
  const {
4843
5098
  selectedMarketType,
4844
5099
  onMarketTypeChange,
4845
5100
  className,
4846
- position = "bottom"
5101
+ position = "bottom",
5102
+ tabs
4847
5103
  } = props;
5104
+ const { t } = i18n.useTranslation();
5105
+ const orderedOptions = React6__default.default.useMemo(() => {
5106
+ if (!tabs) return [];
5107
+ return tabs.filter(
5108
+ (tab) => isCustomMarketTab(tab) || isBuiltInMarketTab(tab) && tab.type !== "favorites"
5109
+ );
5110
+ }, [tabs]);
5111
+ const hasFavoritesTab = React6__default.default.useMemo(() => {
5112
+ return tabs?.some(
5113
+ (tab) => isBuiltInMarketTab(tab) && tab.type === "favorites"
5114
+ );
5115
+ }, [tabs]);
4848
5116
  const [isOpen, setIsOpen] = React6.useState(false);
4849
5117
  const dropdownRef = React6.useRef(null);
4850
5118
  const [, favorite] = hooks.useMarkets(hooks.MarketsType.FAVORITES);
4851
5119
  const hasFavorites = (favorite?.favorites?.length || 0) > 0;
5120
+ const titleOverrides = React6__default.default.useMemo(
5121
+ () => ({
5122
+ all: t("markets.allMarkets"),
5123
+ newListing: t("markets.newListings"),
5124
+ recent: t("markets.recent")
5125
+ }),
5126
+ [t]
5127
+ );
5128
+ const getOptionLabel = React6.useCallback(
5129
+ (tab) => resolveTabTitle(tab, titleOverrides, t("common.rwa")),
5130
+ [t, titleOverrides]
5131
+ );
4852
5132
  React6.useEffect(() => {
4853
5133
  const handleClickOutside = (event) => {
4854
5134
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -4914,41 +5194,46 @@ var init_marketTypeFilter_ui = __esm({
4914
5194
  wrap: "wrap",
4915
5195
  gapY: 1,
4916
5196
  className: "oui-gap-x-2 md:oui-gap-x-3",
4917
- children: marketTypeBase.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
4918
- ui.Flex,
4919
- {
4920
- className: ui.cn("oui-cursor-pointer"),
4921
- itemAlign: "center",
4922
- onClick: () => handleOptionClick(option.value),
4923
- children: [
4924
- /* @__PURE__ */ jsxRuntime.jsx(
4925
- ui.Checkbox,
4926
- {
4927
- "data-testid": `oui-testid-marketType-${option.value}-checkBox`,
4928
- id: `toggle_market_type_${option.value}`,
4929
- className: "oui-peer",
4930
- color: "white",
4931
- checked: selectedMarketType === option.value
4932
- }
4933
- ),
4934
- /* @__PURE__ */ jsxRuntime.jsx(
4935
- "label",
4936
- {
4937
- htmlFor: `toggle_market_type_${option.value}`,
4938
- className: ui.cn(
4939
- "oui-text-2xs oui-ml-1",
4940
- "oui-break-normal oui-whitespace-nowrap oui-cursor-pointer"
4941
- ),
4942
- children: option.translationKey
4943
- }
4944
- )
4945
- ]
4946
- },
4947
- option.value
4948
- ))
5197
+ children: orderedOptions.map((tab) => {
5198
+ const optionValue = isCustomMarketTab(tab) ? tab.id : tab.type;
5199
+ const isActive = selectedMarketType === optionValue;
5200
+ const htmlId = `toggle_market_type_${optionValue}`;
5201
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5202
+ ui.Flex,
5203
+ {
5204
+ className: ui.cn("oui-cursor-pointer"),
5205
+ itemAlign: "center",
5206
+ onClick: () => handleOptionClick(optionValue),
5207
+ children: [
5208
+ /* @__PURE__ */ jsxRuntime.jsx(
5209
+ ui.Checkbox,
5210
+ {
5211
+ "data-testid": `oui-testid-marketType-${optionValue}-checkBox`,
5212
+ id: htmlId,
5213
+ className: "oui-peer",
5214
+ color: "white",
5215
+ checked: isActive
5216
+ }
5217
+ ),
5218
+ /* @__PURE__ */ jsxRuntime.jsx(
5219
+ "label",
5220
+ {
5221
+ htmlFor: htmlId,
5222
+ className: ui.cn(
5223
+ "oui-text-2xs oui-ml-1",
5224
+ "oui-break-normal oui-whitespace-nowrap oui-cursor-pointer"
5225
+ ),
5226
+ children: getOptionLabel(tab)
5227
+ }
5228
+ )
5229
+ ]
5230
+ },
5231
+ optionValue
5232
+ );
5233
+ })
4949
5234
  }
4950
5235
  ),
4951
- hasFavorites && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5236
+ hasFavoritesTab && hasFavorites && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4952
5237
  /* @__PURE__ */ jsxRuntime.jsx(
4953
5238
  ui.Divider,
4954
5239
  {
@@ -5027,6 +5312,7 @@ __export(horizontalMarkets_ui_exports, {
5027
5312
  exports.HorizontalMarkets = void 0;
5028
5313
  var init_horizontalMarkets_ui = __esm({
5029
5314
  "src/components/horizontalMarkets/horizontalMarkets.ui.tsx"() {
5315
+ init_marketsProvider();
5030
5316
  init_marketItem_ui();
5031
5317
  init_marketTypeFilter_ui();
5032
5318
  exports.HorizontalMarkets = React6__default.default.memo((props) => {
@@ -5040,6 +5326,7 @@ var init_horizontalMarkets_ui = __esm({
5040
5326
  className,
5041
5327
  dropdownPos
5042
5328
  } = props;
5329
+ const { tabs } = useMarketsContext();
5043
5330
  const renderMarketItem = React6__default.default.useCallback(
5044
5331
  (symbol, index) => {
5045
5332
  const data = tickerData[symbol];
@@ -5098,7 +5385,8 @@ var init_horizontalMarkets_ui = __esm({
5098
5385
  {
5099
5386
  selectedMarketType,
5100
5387
  onMarketTypeChange,
5101
- position: dropdownPos
5388
+ position: dropdownPos,
5389
+ tabs
5102
5390
  }
5103
5391
  ),
5104
5392
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5315,12 +5603,15 @@ init_favoritesTabs();
5315
5603
  init_expandMarkets();
5316
5604
 
5317
5605
  // src/components/subMenuMarkets/subMenuMarkets.ui.tsx
5318
- init_icons();
5606
+ init_useCommunityTabs();
5319
5607
  init_type();
5608
+ init_communityBrokerTabs();
5320
5609
  init_favoritesTabs();
5321
5610
  init_marketsList();
5611
+ init_marketsProvider();
5322
5612
  init_rwaTab();
5323
5613
  init_useFavoritesExtraProps();
5614
+ init_tabUtils();
5324
5615
  init_symbolDisplay();
5325
5616
  var LIST_ROW_COMPACT = "oui-h-auto";
5326
5617
  var TABLE_CLASSNAMES = {
@@ -5357,8 +5648,10 @@ var MarketTabPanel = ({
5357
5648
  };
5358
5649
  var SubMenuMarkets = (props) => {
5359
5650
  const { activeTab, onTabChange, className, tabSort, onTabSort } = props;
5360
- const { t } = i18n.useTranslation();
5361
5651
  const { getFavoritesProps } = useFavoritesProps();
5652
+ const builtInTitles = useBuiltInTitles();
5653
+ const { tabs } = useMarketsContext();
5654
+ const tabDataFilters = useCustomTabDataFilters(tabs);
5362
5655
  const getColumns = (_favorite, _isFavoritesList) => {
5363
5656
  return [
5364
5657
  {
@@ -5376,7 +5669,72 @@ var SubMenuMarkets = (props) => {
5376
5669
  ] }) });
5377
5670
  }
5378
5671
  }
5379
- ];
5672
+ ];
5673
+ };
5674
+ const renderBuiltInContent = (tabType) => {
5675
+ if (tabType === "favorites" /* Favorites */) {
5676
+ const favProps = getFavoritesProps("favorites" /* Favorites */);
5677
+ return /* @__PURE__ */ jsxRuntime.jsx(
5678
+ MarketTabPanel,
5679
+ {
5680
+ type: "favorites" /* Favorites */,
5681
+ getColumns,
5682
+ dataFilter: favProps?.dataFilter,
5683
+ renderHeader: (favorite) => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { className: "oui-px-1 oui-my-1", children: /* @__PURE__ */ jsxRuntime.jsx(exports.FavoritesTabWidget, { favorite, size: "sm" }) }),
5684
+ initialSort: tabSort["favorites" /* Favorites */],
5685
+ onSort: onTabSort("favorites" /* Favorites */),
5686
+ emptyView: /* @__PURE__ */ jsxRuntime.jsx(ui.EmptyDataState, {})
5687
+ }
5688
+ );
5689
+ }
5690
+ return /* @__PURE__ */ jsxRuntime.jsx(
5691
+ MarketTabPanel,
5692
+ {
5693
+ type: tabType,
5694
+ getColumns,
5695
+ initialSort: tabSort[tabType],
5696
+ onSort: onTabSort(tabType)
5697
+ }
5698
+ );
5699
+ };
5700
+ const renderCommunityContent = () => {
5701
+ return /* @__PURE__ */ jsxRuntime.jsx(
5702
+ CommunityBrokerTabs,
5703
+ {
5704
+ storageKey: "orderly_submenu_markets_community_sel_sub_tab",
5705
+ classNames: {
5706
+ tabsList: "oui-px-1 oui-pt-1 oui-pb-2",
5707
+ tabsContent: "oui-h-full",
5708
+ scrollIndicator: "oui-mx-1"
5709
+ },
5710
+ className: ui.cn("oui-subMenuMarkets-community-tabs", cls2),
5711
+ showScrollIndicator: true,
5712
+ renderPanel: (selected) => /* @__PURE__ */ jsxRuntime.jsx(
5713
+ MarketTabPanel,
5714
+ {
5715
+ type: "all" /* All */,
5716
+ getColumns,
5717
+ dataFilter: createCommunityBrokerFilter(selected),
5718
+ initialSort: tabSort["community" /* Community */],
5719
+ onSort: onTabSort("community" /* Community */)
5720
+ }
5721
+ )
5722
+ }
5723
+ );
5724
+ };
5725
+ const renderCustomContent = (key) => {
5726
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls2, children: /* @__PURE__ */ jsxRuntime.jsx(
5727
+ exports.MarketsListWidget,
5728
+ {
5729
+ type: "all" /* All */,
5730
+ getColumns,
5731
+ tableClassNames: TABLE_CLASSNAMES,
5732
+ rowClassName: LIST_ROW_COMPACT,
5733
+ dataFilter: (data) => tabDataFilters[key]?.(data) ?? data,
5734
+ initialSort: tabSort[key],
5735
+ onSort: onTabSort(key)
5736
+ }
5737
+ ) });
5380
5738
  };
5381
5739
  return /* @__PURE__ */ jsxRuntime.jsxs(
5382
5740
  ui.Box,
@@ -5388,7 +5746,7 @@ var SubMenuMarkets = (props) => {
5388
5746
  height: "100%",
5389
5747
  children: [
5390
5748
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { className: "oui-p-1", children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(LazySearchInput3, {}) }) }),
5391
- /* @__PURE__ */ jsxRuntime.jsxs(
5749
+ /* @__PURE__ */ jsxRuntime.jsx(
5392
5750
  ui.Tabs,
5393
5751
  {
5394
5752
  variant: "contained",
@@ -5402,114 +5760,24 @@ var SubMenuMarkets = (props) => {
5402
5760
  },
5403
5761
  className: ui.cn(cls2, "oui-subMenuMarkets-tabs oui-my-1.5"),
5404
5762
  showScrollIndicator: true,
5405
- children: [
5406
- /* @__PURE__ */ jsxRuntime.jsx(
5407
- ui.TabPanel,
5408
- {
5409
- classNames: {
5410
- trigger: "oui-tabs-favorites-trigger",
5411
- content: "oui-tabs-favorites-content"
5412
- },
5413
- title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
5414
- value: "favorites" /* Favorites */,
5415
- children: (() => {
5416
- const favProps = getFavoritesProps("favorites" /* Favorites */);
5417
- return /* @__PURE__ */ jsxRuntime.jsx(
5418
- MarketTabPanel,
5419
- {
5420
- type: "favorites" /* Favorites */,
5421
- getColumns,
5422
- dataFilter: favProps?.dataFilter,
5423
- renderHeader: (favorite) => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { className: "oui-px-1 oui-my-1", children: /* @__PURE__ */ jsxRuntime.jsx(exports.FavoritesTabWidget, { favorite, size: "sm" }) }),
5424
- initialSort: tabSort["favorites" /* Favorites */],
5425
- onSort: onTabSort("favorites" /* Favorites */),
5426
- emptyView: /* @__PURE__ */ jsxRuntime.jsx(ui.EmptyDataState, {})
5427
- }
5428
- );
5429
- })()
5430
- }
5431
- ),
5432
- /* @__PURE__ */ jsxRuntime.jsx(
5433
- ui.TabPanel,
5434
- {
5435
- classNames: {
5436
- trigger: "oui-tabs-all-trigger",
5437
- content: "oui-tabs-all-content"
5438
- },
5439
- title: t("common.all"),
5440
- value: "all" /* All */,
5441
- children: /* @__PURE__ */ jsxRuntime.jsx(
5442
- MarketTabPanel,
5443
- {
5444
- type: "all" /* All */,
5445
- getColumns,
5446
- initialSort: tabSort["all" /* All */],
5447
- onSort: onTabSort("all" /* All */)
5448
- }
5449
- )
5450
- }
5451
- ),
5452
- /* @__PURE__ */ jsxRuntime.jsx(
5453
- ui.TabPanel,
5454
- {
5455
- classNames: {
5456
- trigger: "oui-tabs-rwa-trigger",
5457
- content: "oui-tabs-rwa-content"
5458
- },
5459
- title: /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {}),
5460
- value: "rwa" /* Rwa */,
5461
- children: /* @__PURE__ */ jsxRuntime.jsx(
5462
- MarketTabPanel,
5463
- {
5464
- type: "rwa" /* Rwa */,
5465
- getColumns,
5466
- initialSort: tabSort["rwa" /* Rwa */],
5467
- onSort: onTabSort("rwa" /* Rwa */)
5468
- }
5469
- )
5470
- }
5471
- ),
5472
- /* @__PURE__ */ jsxRuntime.jsx(
5473
- ui.TabPanel,
5474
- {
5475
- classNames: {
5476
- trigger: "oui-tabs-newListings-trigger",
5477
- content: "oui-tabs-newListings-content"
5478
- },
5479
- title: t("markets.newListings"),
5480
- value: "newListing" /* NewListing */,
5481
- children: /* @__PURE__ */ jsxRuntime.jsx(
5482
- MarketTabPanel,
5483
- {
5484
- type: "newListing" /* NewListing */,
5485
- getColumns,
5486
- initialSort: tabSort["newListing" /* NewListing */],
5487
- onSort: onTabSort("newListing" /* NewListing */)
5488
- }
5489
- )
5490
- }
5491
- ),
5492
- /* @__PURE__ */ jsxRuntime.jsx(
5763
+ children: tabs?.map((tab, index) => {
5764
+ const key = tabKey(tab, index);
5765
+ const isBuiltIn = isBuiltInMarketTab(tab);
5766
+ const isCommunity = isBuiltIn && tab.type === "community" /* Community */;
5767
+ return /* @__PURE__ */ jsxRuntime.jsx(
5493
5768
  ui.TabPanel,
5494
5769
  {
5495
5770
  classNames: {
5496
- trigger: "oui-tabs-recent-trigger",
5497
- content: "oui-tabs-recent-content"
5771
+ trigger: `oui-tabs-${key}-trigger`,
5772
+ content: `oui-tabs-${key}-content`
5498
5773
  },
5499
- title: t("markets.recent"),
5500
- value: "recent" /* Recent */,
5501
- children: /* @__PURE__ */ jsxRuntime.jsx(
5502
- MarketTabPanel,
5503
- {
5504
- type: "recent" /* Recent */,
5505
- getColumns,
5506
- initialSort: tabSort["recent" /* Recent */],
5507
- onSort: onTabSort("recent" /* Recent */)
5508
- }
5509
- )
5510
- }
5511
- )
5512
- ]
5774
+ title: resolveTabTitle(tab, builtInTitles, /* @__PURE__ */ jsxRuntime.jsx(RwaIconTab, {})),
5775
+ value: key,
5776
+ children: isCommunity ? renderCommunityContent() : isBuiltIn ? renderBuiltInContent(tab.type) : renderCustomContent(key)
5777
+ },
5778
+ key
5779
+ );
5780
+ })
5513
5781
  }
5514
5782
  )
5515
5783
  ]
@@ -5519,6 +5787,7 @@ var SubMenuMarkets = (props) => {
5519
5787
 
5520
5788
  // src/components/subMenuMarkets/subMenuMarkets.widget.tsx
5521
5789
  init_marketsProvider();
5790
+ init_useMarketCategories();
5522
5791
 
5523
5792
  // src/components/subMenuMarkets/subMenuMarkets.script.ts
5524
5793
  init_constant();
@@ -5563,11 +5832,13 @@ var SubMenuMarketsWidget = (props) => {
5563
5832
  activeTab: props.activeTab,
5564
5833
  onTabChange: props.onTabChange
5565
5834
  });
5835
+ const tabs = useMarketCategories("subMenuMarkets");
5566
5836
  return /* @__PURE__ */ jsxRuntime.jsx(
5567
5837
  exports.MarketsProvider,
5568
5838
  {
5569
5839
  symbol: props.symbol,
5570
5840
  onSymbolChange: props.onSymbolChange,
5841
+ tabs,
5571
5842
  children: /* @__PURE__ */ jsxRuntime.jsx(
5572
5843
  SubMenuMarkets,
5573
5844
  {
@@ -5597,7 +5868,6 @@ init_type();
5597
5868
  init_useTabSort();
5598
5869
  var SIDE_MARKETS_SEL_TAB_KEY2 = "orderly_side_markets_sel_tab_key";
5599
5870
  var useSideMarketsScript = (options) => {
5600
- const [panelSize, setPanelSize] = React6.useState(options?.panelSize);
5601
5871
  const [activeTab, setActiveTab] = hooks.useLocalStorage(
5602
5872
  SIDE_MARKETS_SEL_TAB_KEY2,
5603
5873
  "all" /* All */
@@ -5605,26 +5875,25 @@ var useSideMarketsScript = (options) => {
5605
5875
  const { tabSort } = useTabSort({
5606
5876
  storageKey: SIDE_MARKETS_TAB_SORT_STORAGE_KEY
5607
5877
  });
5608
- const onPanelSizeChange = React6.useCallback(
5878
+ const panelSize = React6.useMemo(() => {
5879
+ if (options?.collapsed) {
5880
+ return "small";
5881
+ }
5882
+ return options?.panelSize || "large";
5883
+ }, [options?.collapsed, options?.panelSize]);
5884
+ React6.useCallback(
5609
5885
  (size) => {
5610
5886
  if (typeof options?.onPanelSizeChange === "function") {
5611
5887
  options.onPanelSizeChange(size);
5612
- } else {
5613
- setPanelSize(size);
5614
5888
  }
5615
5889
  },
5616
5890
  [options?.onPanelSizeChange]
5617
5891
  );
5618
- React6.useEffect(() => {
5619
- setPanelSize(options?.panelSize);
5620
- }, [options?.panelSize]);
5621
5892
  return {
5622
- resizeable: options?.resizeable ?? true,
5623
- panelSize,
5624
- onPanelSizeChange,
5625
5893
  activeTab,
5626
5894
  onTabChange: setActiveTab,
5627
- tabSort
5895
+ tabSort,
5896
+ panelSize
5628
5897
  };
5629
5898
  };
5630
5899
 
@@ -5636,9 +5905,7 @@ var LazySideMarkets = React6__default.default.lazy(
5636
5905
  })
5637
5906
  );
5638
5907
  var SideMarketsWidget = (props) => {
5639
- const state = useSideMarketsScript(
5640
- ramda.pick(["resizeable", "panelSize", "onPanelSizeChange"], props)
5641
- );
5908
+ const state = useSideMarketsScript(props);
5642
5909
  return /* @__PURE__ */ jsxRuntime.jsx(exports.MarketsProvider, { ...ramda.pick(["symbol", "onSymbolChange"], props), children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(LazySideMarkets, { ...state, className: props.className }) }) });
5643
5910
  };
5644
5911
 
@@ -5646,18 +5913,23 @@ var SideMarketsWidget = (props) => {
5646
5913
  init_dropDownMarkets();
5647
5914
 
5648
5915
  // src/components/marketsSheet/marketsSheet.ui.tsx
5649
- init_icons();
5916
+ init_useCommunityTabs();
5650
5917
  init_type();
5918
+ init_communityBrokerTabs();
5651
5919
  init_marketsList();
5920
+ init_marketsProvider();
5652
5921
  init_rwaTab();
5653
5922
  init_searchInput();
5654
5923
  init_useFavoritesExtraProps();
5924
+ init_tabUtils();
5655
5925
 
5656
5926
  // src/components/marketsSheet/column.tsx
5657
- init_column2();
5927
+ init_column();
5658
5928
  var getMarketsSheetColumns = (favorite, isFavoriteList = false) => {
5659
5929
  return [
5660
- getSymbolColumn(favorite, isFavoriteList),
5930
+ getSymbolColumn(favorite, isFavoriteList, {
5931
+ stackLeverageInSecondRow: true
5932
+ }),
5661
5933
  get24hVolOIColumn(),
5662
5934
  getLastAnd24hPercentageColumn(favorite, isFavoriteList)
5663
5935
  ];
@@ -5666,14 +5938,17 @@ var MarketsSheet = (props) => {
5666
5938
  const { className, tabSort, onTabSort } = props;
5667
5939
  const { t } = i18n.useTranslation();
5668
5940
  const { getFavoritesProps, renderEmptyView } = useFavoritesProps();
5669
- const renderTab = (type) => {
5670
- const isFavorites = type === "favorites" /* Favorites */;
5941
+ const { tabs } = useMarketsContext();
5942
+ const builtInTitles = useBuiltInTitles();
5943
+ const tabDataFilters = useCustomTabDataFilters(tabs);
5944
+ const renderBuiltInContent = (tabType) => {
5945
+ const isFavorites = tabType === "favorites" /* Favorites */;
5671
5946
  return /* @__PURE__ */ jsxRuntime.jsx(
5672
5947
  exports.MarketsListWidget,
5673
5948
  {
5674
- type,
5675
- initialSort: tabSort[type],
5676
- onSort: onTabSort(type),
5949
+ type: tabType,
5950
+ initialSort: tabSort[tabType],
5951
+ onSort: onTabSort(tabType),
5677
5952
  getColumns: getMarketsSheetColumns,
5678
5953
  tableClassNames: {
5679
5954
  root: ui.cn("oui-marketsSheet-list", "!oui-bg-base-8"),
@@ -5683,12 +5958,65 @@ var MarketsSheet = (props) => {
5683
5958
  )
5684
5959
  },
5685
5960
  emptyView: renderEmptyView({
5686
- type,
5961
+ type: tabType,
5687
5962
  onClick: () => {
5688
5963
  props.onTabChange("all" /* All */);
5689
5964
  }
5690
5965
  }),
5691
- ...getFavoritesProps(type)
5966
+ ...getFavoritesProps(tabType)
5967
+ }
5968
+ );
5969
+ };
5970
+ const renderCommunityContent = () => {
5971
+ return /* @__PURE__ */ jsxRuntime.jsx(
5972
+ CommunityBrokerTabs,
5973
+ {
5974
+ storageKey: "orderly_markets_sheet_community_sel_sub_tab",
5975
+ classNames: {
5976
+ tabsList: "oui-px-3 oui-pt-1 oui-pb-2",
5977
+ tabsContent: "oui-h-full"
5978
+ },
5979
+ className: ui.cn(
5980
+ "oui-marketsSheet-community-tabs",
5981
+ "oui-h-[calc(100%_-_36px)]"
5982
+ ),
5983
+ showScrollIndicator: true,
5984
+ renderPanel: (selected) => /* @__PURE__ */ jsxRuntime.jsx(
5985
+ exports.MarketsListWidget,
5986
+ {
5987
+ type: "all" /* All */,
5988
+ initialSort: tabSort["community" /* Community */],
5989
+ onSort: onTabSort("community" /* Community */),
5990
+ getColumns: getMarketsSheetColumns,
5991
+ tableClassNames: {
5992
+ root: ui.cn("oui-marketsSheet-list", "!oui-bg-base-8"),
5993
+ scroll: ui.cn(
5994
+ "oui-pb-[env(safe-area-inset-bottom,_20px)]",
5995
+ "oui-h-[calc(100%_-_40px)]"
5996
+ )
5997
+ },
5998
+ dataFilter: createCommunityBrokerFilter(selected)
5999
+ }
6000
+ )
6001
+ }
6002
+ );
6003
+ };
6004
+ const renderCustomContent = (key) => {
6005
+ return /* @__PURE__ */ jsxRuntime.jsx(
6006
+ exports.MarketsListWidget,
6007
+ {
6008
+ type: "all" /* All */,
6009
+ dataFilter: (data) => tabDataFilters[key]?.(data) ?? data,
6010
+ initialSort: tabSort[key],
6011
+ onSort: onTabSort(key),
6012
+ getColumns: getMarketsSheetColumns,
6013
+ tableClassNames: {
6014
+ root: ui.cn("oui-marketsSheet-list", "!oui-bg-base-8"),
6015
+ scroll: ui.cn(
6016
+ "oui-pb-[env(safe-area-inset-bottom,_20px)]",
6017
+ "oui-h-[calc(100%_-_40px)]"
6018
+ )
6019
+ }
5692
6020
  }
5693
6021
  );
5694
6022
  };
@@ -5707,7 +6035,7 @@ var MarketsSheet = (props) => {
5707
6035
  }
5708
6036
  )
5709
6037
  ] }),
5710
- /* @__PURE__ */ jsxRuntime.jsxs(
6038
+ /* @__PURE__ */ jsxRuntime.jsx(
5711
6039
  ui.Tabs,
5712
6040
  {
5713
6041
  variant: "contained",
@@ -5721,44 +6049,24 @@ var MarketsSheet = (props) => {
5721
6049
  },
5722
6050
  className: ui.cn("oui-marketsSheet-tabs", "oui-h-[calc(100%_-_92px)]"),
5723
6051
  showScrollIndicator: true,
5724
- children: [
5725
- /* @__PURE__ */ jsxRuntime.jsx(
5726
- ui.TabPanel,
5727
- {
5728
- classNames: {
5729
- trigger: "oui-tabs-favorites-trigger",
5730
- content: "oui-tabs-favorites-content"
5731
- },
5732
- title: /* @__PURE__ */ jsxRuntime.jsx(FavoritesIcon, {}),
5733
- value: "favorites" /* Favorites */,
5734
- children: renderTab("favorites" /* Favorites */)
5735
- }
5736
- ),
5737
- /* @__PURE__ */ jsxRuntime.jsx(
5738
- ui.TabPanel,
5739
- {
5740
- classNames: {
5741
- trigger: "oui-tabs-all-trigger",
5742
- content: "oui-tabs-all-content"
5743
- },
5744
- title: t("common.all"),
5745
- value: "all" /* All */,
5746
- children: renderTab("all" /* All */)
5747
- }
5748
- ),
5749
- /* @__PURE__ */ jsxRuntime.jsx(
6052
+ children: tabs?.map((tab, index) => {
6053
+ const key = tabKey(tab, index);
6054
+ const isBuiltIn = isBuiltInMarketTab(tab);
6055
+ const isCommunity = isBuiltIn && tab.type === "community" /* Community */;
6056
+ return /* @__PURE__ */ jsxRuntime.jsx(
5750
6057
  ui.TabPanel,
5751
6058
  {
5752
6059
  classNames: {
5753
- trigger: "oui-tabs-rwa-trigger",
5754
- content: "oui-tabs-rwa-content"
6060
+ trigger: `oui-tabs-${key}-trigger`,
6061
+ content: `oui-tabs-${key}-content`
5755
6062
  },
5756
- title: /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {}),
5757
- value: "rwa" /* Rwa */,
5758
- children: renderTab("rwa" /* Rwa */)
5759
- }
5760
- )
5761
- ]
6063
+ title: resolveTabTitle(tab, builtInTitles, /* @__PURE__ */ jsxRuntime.jsx(RwaTab, {})),
6064
+ value: key,
6065
+ children: isCommunity ? renderCommunityContent() : isBuiltIn ? renderBuiltInContent(tab.type) : renderCustomContent(key)
6066
+ },
6067
+ key
6068
+ );
6069
+ })
5762
6070
  }
5763
6071
  )
5764
6072
  ]
@@ -5789,13 +6097,16 @@ function useMarketsSheetScript() {
5789
6097
 
5790
6098
  // src/components/marketsSheet/marketsSheet.widget.tsx
5791
6099
  init_marketsProvider();
6100
+ init_useMarketCategories();
5792
6101
  var MarketsSheetWidget = (props) => {
5793
6102
  const state = useMarketsSheetScript();
6103
+ const tabs = useMarketCategories("marketsSheet");
5794
6104
  return /* @__PURE__ */ jsxRuntime.jsx(
5795
6105
  exports.MarketsProvider,
5796
6106
  {
5797
6107
  symbol: props.symbol,
5798
6108
  onSymbolChange: props.onSymbolChange,
6109
+ tabs,
5799
6110
  children: /* @__PURE__ */ jsxRuntime.jsx(MarketsSheet, { ...state, className: props.className })
5800
6111
  }
5801
6112
  );
@@ -5803,6 +6114,7 @@ var MarketsSheetWidget = (props) => {
5803
6114
 
5804
6115
  // src/components/symbolInfoBar/symbolInfoBar.ui.tsx
5805
6116
  init_icons();
6117
+ init_symbolBadge();
5806
6118
  init_symbolDisplay();
5807
6119
  var RwaTooltip = (props) => {
5808
6120
  const { isRwa, open, closeTimeInterval, openTimeInterval } = props;
@@ -5959,7 +6271,7 @@ var SymbolInfoBar = (props) => {
5959
6271
  className: "oui-h-5 oui-cursor-pointer oui-gap-x-[6px]",
5960
6272
  onClick: onSymbol,
5961
6273
  children: [
5962
- /* @__PURE__ */ jsxRuntime.jsx(exports.SymbolDisplay, { formatString: "base", size: "sm", children: symbol }),
6274
+ /* @__PURE__ */ jsxRuntime.jsx(exports.SymbolDisplay, { formatString: "base", size: "sm", showBadge: false, children: symbol }),
5963
6275
  /* @__PURE__ */ jsxRuntime.jsx(TriangleDownIcon, { className: "oui-size-[14px] oui-text-base-contrast-54" })
5964
6276
  ]
5965
6277
  }
@@ -5967,32 +6279,37 @@ var SymbolInfoBar = (props) => {
5967
6279
  return /* @__PURE__ */ jsxRuntime.jsxs(
5968
6280
  ui.Flex,
5969
6281
  {
6282
+ intensity: 900,
6283
+ mx: 1,
6284
+ px: 3,
6285
+ py: 2,
5970
6286
  className: ui.cn(
5971
6287
  "oui-symbol-info-bar-mobile",
5972
- "oui-h-full oui-font-semibold",
6288
+ "oui-h-full oui-font-semibold oui-rounded-xl",
5973
6289
  props.className
5974
6290
  ),
5975
6291
  children: [
5976
6292
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 3, className: "oui-h-full oui-flex-1 oui-overflow-hidden", children: [
5977
6293
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 3, children: [
5978
6294
  /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol, size: "xs" }),
5979
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", children: [
6295
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", gap: 1, children: [
5980
6296
  symbolView,
5981
6297
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
5982
6298
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "xs", color: "primary", children: [
5983
6299
  leverage,
5984
6300
  "x"
5985
6301
  ] }),
5986
- /* @__PURE__ */ jsxRuntime.jsx(
5987
- RwaTooltip,
5988
- {
5989
- isRwa,
5990
- open,
5991
- closeTimeInterval,
5992
- openTimeInterval
5993
- }
5994
- )
5995
- ] })
6302
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol })
6303
+ ] }),
6304
+ /* @__PURE__ */ jsxRuntime.jsx(
6305
+ RwaTooltip,
6306
+ {
6307
+ isRwa,
6308
+ open,
6309
+ closeTimeInterval,
6310
+ openTimeInterval
6311
+ }
6312
+ )
5996
6313
  ] })
5997
6314
  ] }),
5998
6315
  /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-h-[38px]", direction: "vertical", intensity: 8 }),
@@ -6202,6 +6519,7 @@ var FundingRateHintWidget = (props) => {
6202
6519
  };
6203
6520
 
6204
6521
  // src/components/symbolInfoBarFull/symbolInfoBarFull.ui.tsx
6522
+ init_symbolBadge();
6205
6523
  init_symbolDisplay();
6206
6524
  var LazyDropDownMarketsWidget = React6__default.default.lazy(
6207
6525
  () => Promise.resolve().then(() => (init_dropDownMarkets(), dropDownMarkets_exports)).then((mod) => {
@@ -6218,6 +6536,91 @@ var LazyDataItem = React6__default.default.lazy(
6218
6536
  return { default: mod.DataItem };
6219
6537
  })
6220
6538
  );
6539
+ var RISK_NOTICE_LEARN_MORE_URL = "https://orderly.network";
6540
+ var SymbolInfoBarRiskNotice = ({ className, visible, symbolWithBroker, brokerName, autoHeight }) => {
6541
+ const { t } = i18n.useTranslation();
6542
+ if (!visible) return null;
6543
+ return /* @__PURE__ */ jsxRuntime.jsx(
6544
+ "a",
6545
+ {
6546
+ href: RISK_NOTICE_LEARN_MORE_URL,
6547
+ target: "_blank",
6548
+ rel: "noopener noreferrer",
6549
+ className: ui.cn(
6550
+ "oui-symbol-info-bar-risk-notice oui-w-full oui-bg-warning-darken/10 oui-rounded-none oui-text-warning-darken hover:oui-cursor-pointer oui-block",
6551
+ className
6552
+ ),
6553
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
6554
+ ui.Flex,
6555
+ {
6556
+ itemAlign: "center",
6557
+ gap: 2,
6558
+ className: autoHeight ? "oui-min-h-0 oui-py-2 oui-px-2" : "oui-h-[46px] oui-px-3",
6559
+ children: [
6560
+ /* @__PURE__ */ jsxRuntime.jsx(ui.WarningIcon, { className: "oui-shrink-0 oui-size-4 oui-text-warning-darken" }),
6561
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xs", className: "oui-text-warning-darken oui-flex-1", children: [
6562
+ t("markets.symbolInfoBar.riskNotice.content", {
6563
+ symbolWithBroker,
6564
+ brokerName
6565
+ }),
6566
+ " ",
6567
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-underline", children: t("common.learnMore") })
6568
+ ] })
6569
+ ]
6570
+ }
6571
+ )
6572
+ }
6573
+ );
6574
+ };
6575
+ var SymbolInfoBarDesktop = ({
6576
+ className,
6577
+ trailing,
6578
+ leftSection,
6579
+ priceSection,
6580
+ scrollableContent,
6581
+ containerRef,
6582
+ leadingVisible,
6583
+ tailingVisible,
6584
+ onScroll
6585
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
6586
+ ui.Flex,
6587
+ {
6588
+ intensity: 900,
6589
+ r: "2xl",
6590
+ px: 3,
6591
+ className: ui.cn(
6592
+ "oui-symbol-info-bar-desktop",
6593
+ "oui-font-semibold",
6594
+ "oui-flex-1 oui-w-full",
6595
+ "oui-py-2",
6596
+ className
6597
+ ),
6598
+ style: {
6599
+ transform: "translateZ(0)",
6600
+ willChange: "transform"
6601
+ },
6602
+ children: [
6603
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 6, className: "oui-h-full oui-flex-1 oui-overflow-hidden", children: [
6604
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gapX: 1, className: "oui-flex-none oui-shrink-0", children: leftSection }),
6605
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-h-[26px]", direction: "vertical", intensity: 8 }),
6606
+ priceSection,
6607
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-relative oui-h-full oui-overflow-hidden", children: [
6608
+ /* @__PURE__ */ jsxRuntime.jsx(
6609
+ "div",
6610
+ {
6611
+ ref: containerRef,
6612
+ className: "oui-hide-scrollbar oui-h-full oui-overflow-x-auto",
6613
+ children: scrollableContent
6614
+ }
6615
+ ),
6616
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollIndicator2, { leading: true, onClick: onScroll, visible: leadingVisible }),
6617
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollIndicator2, { tailing: true, onClick: onScroll, visible: tailingVisible })
6618
+ ] })
6619
+ ] }),
6620
+ trailing
6621
+ ]
6622
+ }
6623
+ );
6221
6624
  var SymbolInfoBarFull = (props) => {
6222
6625
  const {
6223
6626
  symbol,
@@ -6243,6 +6646,10 @@ var SymbolInfoBarFull = (props) => {
6243
6646
  showCountdown
6244
6647
  } = props;
6245
6648
  const { t } = i18n.useTranslation();
6649
+ const { brokerId, brokerName, brokerNameRaw, displayName } = hooks.useBadgeBySymbol(symbol);
6650
+ const isCommunityListed = Boolean(brokerId ?? brokerName);
6651
+ const baseFromSymbol = symbol?.split("_")[1] ?? symbol;
6652
+ const symbolWithBroker = brokerName != null ? `${baseFromSymbol}-${brokerNameRaw}` : displayName ?? symbol;
6246
6653
  const favoriteIcon = /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(LazyFavoritesDropdownMenuWidget, { row: { symbol }, favorite, children: /* @__PURE__ */ jsxRuntime.jsx(
6247
6654
  ui.Flex,
6248
6655
  {
@@ -6267,7 +6674,7 @@ var SymbolInfoBarFull = (props) => {
6267
6674
  contentClassName: "oui-w-[580px] oui-h-[496px]",
6268
6675
  symbol: props.symbol,
6269
6676
  onSymbolChange: props.onSymbolChange,
6270
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, className: "oui-cursor-pointer", children: [
6677
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { direction: "column", gap: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, className: "oui-cursor-pointer", children: [
6271
6678
  /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol, className: "oui-size-4" }),
6272
6679
  /* @__PURE__ */ jsxRuntime.jsx(
6273
6680
  exports.SymbolDisplay,
@@ -6275,22 +6682,26 @@ var SymbolInfoBarFull = (props) => {
6275
6682
  formatString: "base",
6276
6683
  size: "xs",
6277
6684
  className: "oui-text-base-contrast",
6685
+ showBadge: false,
6278
6686
  children: symbol
6279
6687
  }
6280
6688
  ),
6281
6689
  /* @__PURE__ */ jsxRuntime.jsx(TriangleDownIcon, { className: "oui-text-base-contrast-54" })
6282
- ] })
6690
+ ] }) })
6283
6691
  }
6284
6692
  ),
6285
- isRwa && /* @__PURE__ */ jsxRuntime.jsx(
6286
- RwaTooltip,
6287
- {
6288
- isRwa,
6289
- open,
6290
- closeTimeInterval,
6291
- openTimeInterval
6292
- }
6293
- )
6693
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
6694
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol }),
6695
+ isRwa && /* @__PURE__ */ jsxRuntime.jsx(
6696
+ RwaTooltip,
6697
+ {
6698
+ isRwa,
6699
+ open,
6700
+ closeTimeInterval,
6701
+ openTimeInterval
6702
+ }
6703
+ )
6704
+ ] })
6294
6705
  ]
6295
6706
  }
6296
6707
  ) });
@@ -6319,129 +6730,92 @@ var SymbolInfoBarFull = (props) => {
6319
6730
  }
6320
6731
  )
6321
6732
  ] });
6322
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", className: "oui-h-full oui-w-full", children: [
6323
- /* @__PURE__ */ jsxRuntime.jsxs(
6324
- ui.Flex,
6733
+ const leftSection = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6734
+ favoriteIcon,
6735
+ symbolView
6736
+ ] });
6737
+ const priceSection = /* @__PURE__ */ jsxRuntime.jsx(
6738
+ ui.Tooltip,
6739
+ {
6740
+ content: t("markets.symbolInfoBar.lastPrice.tooltip"),
6741
+ className: "oui-max-w-[240px]",
6742
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-cursor-pointer oui-border-b oui-border-dashed oui-border-line-12 oui-inline-block", children: price })
6743
+ }
6744
+ );
6745
+ const scrollableContent = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 8, height: "100%", children: [
6746
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: leadingElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(LazyDataItem, { label: t("markets.column.24hChange"), value: change }) }) }),
6747
+ /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6748
+ LazyDataItem,
6325
6749
  {
6326
- className: ui.cn(
6327
- "oui-symbol-info-bar-desktop",
6328
- "oui-font-semibold",
6329
- "oui-flex-1 oui-w-full",
6330
- props.className
6750
+ label: t("markets.symbolInfoBar.Mark"),
6751
+ value: /* @__PURE__ */ jsxRuntime.jsx(
6752
+ ui.Text.numeral,
6753
+ {
6754
+ dp: quotoDp,
6755
+ "data-testid": "oui-testid-tokenInfo-markPrice-value",
6756
+ children: data?.["mark_price"]
6757
+ }
6331
6758
  ),
6332
- style: {
6333
- transform: "translateZ(0)",
6334
- willChange: "transform"
6335
- },
6336
- children: [
6337
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 6, className: "oui-h-full oui-flex-1 oui-overflow-hidden", children: [
6338
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
6339
- favoriteIcon,
6340
- symbolView
6341
- ] }),
6342
- /* @__PURE__ */ jsxRuntime.jsx(
6343
- ui.Divider,
6344
- {
6345
- className: "oui-h-[26px]",
6346
- direction: "vertical",
6347
- intensity: 8
6348
- }
6349
- ),
6350
- /* @__PURE__ */ jsxRuntime.jsx(
6351
- ui.Tooltip,
6352
- {
6353
- content: t("markets.symbolInfoBar.lastPrice.tooltip"),
6354
- className: "oui-max-w-[240px]",
6355
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-cursor-pointer oui-border-b oui-border-dashed oui-border-line-12 oui-inline-block", children: price })
6356
- }
6357
- ),
6358
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-relative oui-h-full oui-overflow-hidden", children: [
6359
- /* @__PURE__ */ jsxRuntime.jsx(
6360
- "div",
6361
- {
6362
- ref: containerRef,
6363
- className: "oui-hide-scrollbar oui-h-full oui-overflow-x-auto",
6364
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 8, height: "100%", children: [
6365
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: leadingElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6366
- LazyDataItem,
6367
- {
6368
- label: t("markets.column.24hChange"),
6369
- value: change
6370
- }
6371
- ) }) }),
6372
- /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6373
- LazyDataItem,
6374
- {
6375
- label: t("markets.symbolInfoBar.Mark"),
6376
- value: /* @__PURE__ */ jsxRuntime.jsx(
6377
- ui.Text.numeral,
6378
- {
6379
- dp: quotoDp,
6380
- "data-testid": "oui-testid-tokenInfo-markPrice-value",
6381
- children: data?.["mark_price"]
6382
- }
6383
- ),
6384
- hint: t("markets.symbolInfoBar.Mark.tooltip")
6385
- }
6386
- ) }),
6387
- /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6388
- LazyDataItem,
6389
- {
6390
- label: t("markets.symbolInfoBar.Index"),
6391
- value: /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: quotoDp, children: data?.["index_price"] }),
6392
- hint: t("markets.symbolInfoBar.Index.tooltip")
6393
- }
6394
- ) }),
6395
- /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6396
- LazyDataItem,
6397
- {
6398
- label: t("markets.symbolInfoBar.24hVolume"),
6399
- value: /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, children: data?.["24h_amount"] }),
6400
- hint: t("markets.symbolInfoBar.24hVolume.tooltip")
6401
- }
6402
- ) }),
6403
- /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6404
- LazyDataItem,
6405
- {
6406
- label: t("markets.symbolInfoBar.predFundingRate"),
6407
- value: /* @__PURE__ */ jsxRuntime.jsx(FundingRate, { symbol }),
6408
- hint: /* @__PURE__ */ jsxRuntime.jsx(FundingRateHintWidget, { symbol })
6409
- }
6410
- ) }),
6411
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: tailingElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6412
- LazyDataItem,
6413
- {
6414
- label: t("markets.openInterest"),
6415
- value: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6416
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, children: openInterest }),
6417
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, children: ` USDC` })
6418
- ] }),
6419
- hint: t("markets.openInterest.tooltip")
6420
- }
6421
- ) }) })
6422
- ] })
6423
- }
6424
- ),
6425
- /* @__PURE__ */ jsxRuntime.jsx(
6426
- ScrollIndicator2,
6427
- {
6428
- leading: true,
6429
- onClick: onScoll,
6430
- visible: leadingVisible
6431
- }
6432
- ),
6433
- /* @__PURE__ */ jsxRuntime.jsx(
6434
- ScrollIndicator2,
6435
- {
6436
- tailing: true,
6437
- onClick: onScoll,
6438
- visible: tailingVisible
6439
- }
6440
- )
6441
- ] })
6442
- ] }),
6443
- props.trailing
6444
- ]
6759
+ hint: t("markets.symbolInfoBar.Mark.tooltip")
6760
+ }
6761
+ ) }),
6762
+ /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6763
+ LazyDataItem,
6764
+ {
6765
+ label: t("markets.symbolInfoBar.Index"),
6766
+ value: /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: quotoDp, children: data?.["index_price"] }),
6767
+ hint: t("markets.symbolInfoBar.Index.tooltip")
6768
+ }
6769
+ ) }),
6770
+ /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6771
+ LazyDataItem,
6772
+ {
6773
+ label: t("markets.symbolInfoBar.24hVolume"),
6774
+ value: /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, children: data?.["24h_amount"] }),
6775
+ hint: t("markets.symbolInfoBar.24hVolume.tooltip")
6776
+ }
6777
+ ) }),
6778
+ /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6779
+ LazyDataItem,
6780
+ {
6781
+ label: t("markets.symbolInfoBar.predFundingRate"),
6782
+ value: /* @__PURE__ */ jsxRuntime.jsx(FundingRate, { symbol }),
6783
+ hint: /* @__PURE__ */ jsxRuntime.jsx(FundingRateHintWidget, { symbol })
6784
+ }
6785
+ ) }),
6786
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: tailingElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(React6__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
6787
+ LazyDataItem,
6788
+ {
6789
+ label: t("markets.openInterest"),
6790
+ value: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6791
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "human", dp: 2, children: openInterest }),
6792
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, children: ` USDC` })
6793
+ ] }),
6794
+ hint: t("markets.openInterest.tooltip")
6795
+ }
6796
+ ) }) })
6797
+ ] });
6798
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", className: "oui-h-full oui-w-full", gapY: 1, children: [
6799
+ /* @__PURE__ */ jsxRuntime.jsx(
6800
+ SymbolInfoBarRiskNotice,
6801
+ {
6802
+ visible: isCommunityListed,
6803
+ symbolWithBroker,
6804
+ brokerName: brokerNameRaw ?? brokerName ?? ""
6805
+ }
6806
+ ),
6807
+ /* @__PURE__ */ jsxRuntime.jsx(
6808
+ SymbolInfoBarDesktop,
6809
+ {
6810
+ className: props.className,
6811
+ trailing: props.trailing,
6812
+ leftSection,
6813
+ priceSection,
6814
+ scrollableContent,
6815
+ containerRef,
6816
+ leadingVisible,
6817
+ tailingVisible,
6818
+ onScroll: onScoll
6445
6819
  }
6446
6820
  ),
6447
6821
  showCountdown && /* @__PURE__ */ jsxRuntime.jsx(
@@ -6634,42 +7008,69 @@ function useSymbolInfoBarFullScript(options) {
6634
7008
  openTimeInterval
6635
7009
  };
6636
7010
  }
7011
+ var SymbolInfoBarFullInjectable = ui.injectable(
7012
+ SymbolInfoBarFull,
7013
+ "Trading.SymbolInfoBar.Desktop"
7014
+ );
6637
7015
  var SymbolInfoBarFullWidget = (props) => {
6638
7016
  const { symbol, ...rest } = props;
6639
7017
  const state = useSymbolInfoBarFullScript({ symbol });
6640
- return /* @__PURE__ */ jsxRuntime.jsx(SymbolInfoBarFull, { ...state, ...rest });
7018
+ return /* @__PURE__ */ jsxRuntime.jsx(SymbolInfoBarFullInjectable, { ...state, ...rest });
6641
7019
  };
6642
7020
 
6643
7021
  // src/components/horizontalMarkets/horizontalMarkets.widget.tsx
6644
7022
  init_marketsProvider();
7023
+ init_useMarketCategories();
6645
7024
 
6646
7025
  // src/components/horizontalMarkets/horizontalMarkets.script.ts
6647
7026
  init_constant();
6648
7027
  init_utils();
6649
7028
  init_marketsProvider();
6650
7029
  init_useTabSort();
7030
+ init_tabUtils();
6651
7031
  var useHorizontalMarketsScript = (options) => {
6652
7032
  const {
6653
7033
  symbols: optionSymbols,
6654
7034
  maxItems: optionMaxItems,
6655
7035
  defaultMarketType
6656
7036
  } = options || {};
6657
- const { symbol: currentSymbol, onSymbolChange } = useMarketsContext();
7037
+ const { symbol: currentSymbol, onSymbolChange, tabs } = useMarketsContext();
6658
7038
  const [selectedMarketType, setSelectedMarketType] = hooks.useLocalStorage(
6659
7039
  SIDE_MARKETS_SEL_TAB_KEY,
6660
7040
  defaultMarketType || "all"
6661
7041
  );
7042
+ const availableMarketTypes = React6.useMemo(
7043
+ () => tabs?.map((tab, index) => tabKey(tab, index)) ?? ["all"],
7044
+ [tabs]
7045
+ );
6662
7046
  const MarketsTypeMap3 = {
6663
7047
  all: hooks.MarketsType.ALL,
6664
7048
  recent: hooks.MarketsType.RECENT,
6665
7049
  newListing: hooks.MarketsType.NEW_LISTING,
6666
7050
  favorites: hooks.MarketsType.FAVORITES
6667
7051
  };
6668
- const marketTypeKey = selectedMarketType || "all";
7052
+ const isCustomCategory = typeof selectedMarketType === "string" && !MarketsTypeMap3[selectedMarketType];
7053
+ const marketTypeKey = isCustomCategory ? "all" : selectedMarketType || "all";
6669
7054
  const [markets, favorite] = hooks.useMarkets(
6670
7055
  MarketsTypeMap3[marketTypeKey] || hooks.MarketsType.ALL
6671
7056
  );
7057
+ React6.useEffect(() => {
7058
+ if (!availableMarketTypes.includes(selectedMarketType)) {
7059
+ setSelectedMarketType(availableMarketTypes[0] ?? "all");
7060
+ }
7061
+ }, [availableMarketTypes, selectedMarketType, setSelectedMarketType]);
7062
+ const customCategoryFilter = React6.useMemo(() => {
7063
+ if (!isCustomCategory || !tabs) return null;
7064
+ const customTabs = tabs.filter(isCustomMarketTab);
7065
+ const tab = customTabs.find(
7066
+ (item, index) => tabKey(item, index) === selectedMarketType
7067
+ );
7068
+ return tab ? getCustomTabDataFilter(tab) ?? null : null;
7069
+ }, [isCustomCategory, tabs, selectedMarketType]);
6672
7070
  const filteredMarkets = React6.useMemo(() => {
7071
+ if (isCustomCategory && customCategoryFilter) {
7072
+ return customCategoryFilter(markets);
7073
+ }
6673
7074
  if (selectedMarketType === "favorites") {
6674
7075
  const { favorites, selectedFavoriteTab } = favorite;
6675
7076
  const symbolsInTab = favorites?.filter(
@@ -6691,7 +7092,9 @@ var useHorizontalMarketsScript = (options) => {
6691
7092
  favorite.favorites,
6692
7093
  favorite.selectedFavoriteTab,
6693
7094
  favorite.recent,
6694
- selectedMarketType
7095
+ selectedMarketType,
7096
+ isCustomCategory,
7097
+ customCategoryFilter
6695
7098
  ]);
6696
7099
  const { tabSort } = useTabSort({
6697
7100
  storageKey: SIDE_MARKETS_TAB_SORT_STORAGE_KEY
@@ -6776,7 +7179,8 @@ var HorizontalMarketsWidget = (props) => {
6776
7179
  dropdownPos,
6777
7180
  ...providerProps
6778
7181
  } = props;
6779
- return /* @__PURE__ */ jsxRuntime.jsx(exports.MarketsProvider, { ...providerProps, children: /* @__PURE__ */ jsxRuntime.jsx(
7182
+ const tabs = useMarketCategories("horizontalMarkets");
7183
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.MarketsProvider, { ...providerProps, tabs, children: /* @__PURE__ */ jsxRuntime.jsx(
6780
7184
  HorizontalMarketsInner,
6781
7185
  {
6782
7186
  symbols,
@@ -6796,7 +7200,7 @@ init_marketItem_ui();
6796
7200
  // src/deprecated/newListingList/newListingList.ui.tsx
6797
7201
  init_collapseMarkets();
6798
7202
  init_marketsProvider();
6799
- init_column();
7203
+ init_column2();
6800
7204
  var NewListingList = (props) => {
6801
7205
  const { dataSource, favorite, onSort, loading, getColumns, collapsed } = props;
6802
7206
  const { symbol, onSymbolChange } = useMarketsContext();
@@ -6865,7 +7269,7 @@ var NewListingListWidget = (props) => {
6865
7269
  init_collapseMarkets();
6866
7270
  init_favoritesTabs();
6867
7271
  init_marketsProvider();
6868
- init_column();
7272
+ init_column2();
6869
7273
  var FavoritesList = (props) => {
6870
7274
  const { dataSource, favorite, onSort, loading, getColumns, collapsed } = props;
6871
7275
  const { symbol, onSymbolChange } = useMarketsContext();
@@ -6946,7 +7350,7 @@ var FavoritesListWidget = (props) => {
6946
7350
  // src/deprecated/recentList/recentList.ui.tsx
6947
7351
  init_collapseMarkets();
6948
7352
  init_marketsProvider();
6949
- init_column();
7353
+ init_column2();
6950
7354
  var RecentList = (props) => {
6951
7355
  const { dataSource, favorite, onSort, loading, getColumns, collapsed } = props;
6952
7356
  const { symbol, onSymbolChange } = useMarketsContext();
@@ -7016,6 +7420,7 @@ init_type();
7016
7420
 
7017
7421
  // src/pages/home/page.tsx
7018
7422
  init_marketsProvider();
7423
+ init_useMarketCategories();
7019
7424
  init_type();
7020
7425
  var LazyMarketsHeaderWidget = React6__default.default.lazy(
7021
7426
  () => Promise.resolve().then(() => (init_marketsHeader_widget(), marketsHeader_widget_exports)).then((mod) => {
@@ -7037,6 +7442,7 @@ var MarketsHomePage = (props) => {
7037
7442
  const [activeTab, setActiveTab] = React6.useState(
7038
7443
  "markets" /* Markets */
7039
7444
  );
7445
+ const tabs = useMarketCategories("marketsDataList");
7040
7446
  return /* @__PURE__ */ jsxRuntime.jsx(
7041
7447
  exports.MarketsProvider,
7042
7448
  {
@@ -7044,6 +7450,7 @@ var MarketsHomePage = (props) => {
7044
7450
  onSymbolChange: props.onSymbolChange,
7045
7451
  navProps: props.navProps,
7046
7452
  comparisonProps: props.comparisonProps,
7453
+ tabs,
7047
7454
  children: /* @__PURE__ */ jsxRuntime.jsx(
7048
7455
  "div",
7049
7456
  {
@@ -7167,6 +7574,7 @@ var MarketsMobileContent = (props) => {
7167
7574
  // src/index.ts
7168
7575
  init_marketsProvider();
7169
7576
  init_symbolDisplay();
7577
+ init_builtInTabRegistry();
7170
7578
 
7171
7579
  exports.FavoritesList = FavoritesList;
7172
7580
  exports.FavoritesListWidget = FavoritesListWidget;
@@ -7184,6 +7592,7 @@ exports.SubMenuMarketsWidget = SubMenuMarketsWidget;
7184
7592
  exports.SymbolInfoBar = SymbolInfoBar;
7185
7593
  exports.SymbolInfoBarFull = SymbolInfoBarFull;
7186
7594
  exports.SymbolInfoBarFullWidget = SymbolInfoBarFullWidget;
7595
+ exports.SymbolInfoBarRiskNotice = SymbolInfoBarRiskNotice;
7187
7596
  exports.SymbolInfoBarWidget = SymbolInfoBarWidget;
7188
7597
  exports.useDropDownMarketsScript = useDropDownMarketsScript;
7189
7598
  exports.useExpandMarketsScript = useExpandMarketsScript;