@orderly.network/ui-order-entry 2.10.2 → 2.11.0-alpha.0
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.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +1081 -198
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +964 -81
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React3 = require('react');
|
|
4
4
|
var hooks = require('@orderly.network/hooks');
|
|
5
5
|
var i18n = require('@orderly.network/i18n');
|
|
6
6
|
var reactApp = require('@orderly.network/react-app');
|
|
@@ -15,7 +15,7 @@ var uiLeverage = require('@orderly.network/ui-leverage');
|
|
|
15
15
|
|
|
16
16
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
19
19
|
|
|
20
20
|
// src/orderEntry.ui.tsx
|
|
21
21
|
var AdditionalInfo = (props) => {
|
|
@@ -30,7 +30,7 @@ var AdditionalInfo = (props) => {
|
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
React3.useEffect(() => {
|
|
34
34
|
props.onValueChange?.("visible_quantity", props.hidden ? 0 : 1);
|
|
35
35
|
}, [props.hidden]);
|
|
36
36
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -240,7 +240,7 @@ var AdditionalInfo = (props) => {
|
|
|
240
240
|
);
|
|
241
241
|
};
|
|
242
242
|
function AdditionalConfigButton(props) {
|
|
243
|
-
const [open2, setOpen] =
|
|
243
|
+
const [open2, setOpen] = React3.useState(false);
|
|
244
244
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.PopoverRoot, { open: open2, onOpenChange: setOpen, children: [
|
|
245
245
|
/* @__PURE__ */ jsxRuntime.jsx(ui.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
246
246
|
"button",
|
|
@@ -282,7 +282,7 @@ function AdditionalConfigButton(props) {
|
|
|
282
282
|
}
|
|
283
283
|
var defaultPath = "M10.007 1.302a.74.74 0 0 0-.486.214c-1.033.989-1.349 1.815-.972 2.948-.88.675-1.437.84-2.536.84-1.503 0-2.484.182-3.152.85v.02a1.583 1.583 0 0 0 0 2.248l1.867 1.882-3.181 3.18c-.26.26-.28.696-.02.956.261.26.699.26.959 0l3.193-3.194 1.87 1.861a1.585 1.585 0 0 0 2.25 0h.02c.668-.667.854-1.523.854-3.144 0-1.03.212-1.758.852-2.523 1.233.361 1.95.015 2.961-.995a.68.68 0 0 0 .188-.48c0-.234-.06-.593-.209-1.04a5.34 5.34 0 0 0-1.312-2.103 5.35 5.35 0 0 0-2.104-1.312c-.448-.15-.808-.208-1.042-.208";
|
|
284
284
|
var PinButton = (props) => {
|
|
285
|
-
const [path, setPath] =
|
|
285
|
+
const [path, setPath] = React3.useState(defaultPath);
|
|
286
286
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
287
287
|
"button",
|
|
288
288
|
{
|
|
@@ -605,15 +605,15 @@ var FeesWidget = ({ symbol }) => {
|
|
|
605
605
|
);
|
|
606
606
|
};
|
|
607
607
|
var options = [0.01, 0.05, 0.1];
|
|
608
|
-
var SlippageEditor =
|
|
608
|
+
var SlippageEditor = React3.forwardRef((props, ref) => {
|
|
609
609
|
const { t } = i18n.useTranslation();
|
|
610
|
-
const [value, setValue] =
|
|
611
|
-
const [customValue, setCustomValue] =
|
|
612
|
-
const [error, setError] =
|
|
613
|
-
|
|
610
|
+
const [value, setValue] = React3.useState();
|
|
611
|
+
const [customValue, setCustomValue] = React3.useState("");
|
|
612
|
+
const [error, setError] = React3.useState(void 0);
|
|
613
|
+
React3.useImperativeHandle(ref, () => ({
|
|
614
614
|
getValue: () => customValue ? new utils.Decimal(customValue)?.toNumber() : value
|
|
615
615
|
}));
|
|
616
|
-
|
|
616
|
+
React3.useEffect(() => {
|
|
617
617
|
if (props.initialValue && !options.includes(props.initialValue)) {
|
|
618
618
|
setCustomValue(props.initialValue.toString());
|
|
619
619
|
} else {
|
|
@@ -732,7 +732,7 @@ var SlippageCell = (props) => {
|
|
|
732
732
|
const { t } = i18n.useTranslation();
|
|
733
733
|
const [open2, { setTrue: setOpen, setFalse: setClose, toggle }] = hooks.useBoolean(false);
|
|
734
734
|
const { isMobile } = ui.useScreen();
|
|
735
|
-
const slippageRef =
|
|
735
|
+
const slippageRef = React3.useRef(null);
|
|
736
736
|
const onConfirm = () => {
|
|
737
737
|
const val = slippageRef.current?.getValue();
|
|
738
738
|
props.setSlippage(!val ? "1" : val.toString());
|
|
@@ -908,7 +908,8 @@ var LTVRiskTooltipUI = (props) => {
|
|
|
908
908
|
isThresholdLoading,
|
|
909
909
|
holdingData = [],
|
|
910
910
|
currentLtv,
|
|
911
|
-
onConvert
|
|
911
|
+
onConvert,
|
|
912
|
+
marginMode
|
|
912
913
|
} = props;
|
|
913
914
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
914
915
|
ui.Flex,
|
|
@@ -916,6 +917,7 @@ var LTVRiskTooltipUI = (props) => {
|
|
|
916
917
|
gap: 1,
|
|
917
918
|
className: "oui-orderEntry-ltvRiskTooltip oui-w-72 oui-max-w-72",
|
|
918
919
|
direction: "column",
|
|
920
|
+
itemAlign: "start",
|
|
919
921
|
children: [
|
|
920
922
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", justify: "between", itemAlign: "center", children: [
|
|
921
923
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("common.assets") }),
|
|
@@ -994,7 +996,7 @@ var useConvertThreshold = () => {
|
|
|
994
996
|
error
|
|
995
997
|
};
|
|
996
998
|
};
|
|
997
|
-
var useLTVTooltipScript = () => {
|
|
999
|
+
var useLTVTooltipScript = (marginMode) => {
|
|
998
1000
|
const { data: holdingList = [], isLoading: isHoldingLoading } = hooks.useHoldingStream();
|
|
999
1001
|
const {
|
|
1000
1002
|
ltv_threshold,
|
|
@@ -1025,7 +1027,7 @@ var useLTVTooltipScript = () => {
|
|
|
1025
1027
|
};
|
|
1026
1028
|
});
|
|
1027
1029
|
const currentLtv = hooks.useComputedLTV();
|
|
1028
|
-
const onConvert =
|
|
1030
|
+
const onConvert = React3.useCallback(async () => {
|
|
1029
1031
|
return ui.modal.show("ConvertDialogId");
|
|
1030
1032
|
}, []);
|
|
1031
1033
|
return {
|
|
@@ -1035,18 +1037,21 @@ var useLTVTooltipScript = () => {
|
|
|
1035
1037
|
negative_usdc_threshold,
|
|
1036
1038
|
isThresholdLoading,
|
|
1037
1039
|
currentLtv,
|
|
1038
|
-
onConvert
|
|
1040
|
+
onConvert,
|
|
1041
|
+
marginMode
|
|
1039
1042
|
};
|
|
1040
1043
|
};
|
|
1041
|
-
var LTVRiskTooltipWidget = (
|
|
1042
|
-
|
|
1044
|
+
var LTVRiskTooltipWidget = ({
|
|
1045
|
+
marginMode
|
|
1046
|
+
}) => {
|
|
1047
|
+
const state = useLTVTooltipScript(marginMode);
|
|
1043
1048
|
return /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipUI, { ...state });
|
|
1044
1049
|
};
|
|
1045
1050
|
var Available = (props) => {
|
|
1046
|
-
const { canTrade, currentLtv, quote, freeCollateral } = props;
|
|
1051
|
+
const { canTrade, currentLtv, quote, freeCollateral, marginMode } = props;
|
|
1047
1052
|
const { t } = i18n.useTranslation();
|
|
1048
1053
|
const { isMobile } = ui.useScreen();
|
|
1049
|
-
const showLTV =
|
|
1054
|
+
const showLTV = React3.useMemo(() => {
|
|
1050
1055
|
return typeof currentLtv === "number" && !Number.isNaN(currentLtv) && currentLtv > 0;
|
|
1051
1056
|
}, [currentLtv]);
|
|
1052
1057
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1056,13 +1061,13 @@ var Available = (props) => {
|
|
|
1056
1061
|
justify: "between",
|
|
1057
1062
|
className: "oui-orderEntry-available",
|
|
1058
1063
|
children: [
|
|
1059
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label", size: "2xs", children: t("common.available") }),
|
|
1064
|
+
marginMode === types.MarginMode.ISOLATED ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("transfer.LTV.isolatedModeUsdcOnly"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label oui-cursor-pointer", size: "2xs", children: t("common.available") }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label", size: "2xs", children: t("common.available") }),
|
|
1060
1065
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { itemAlign: "center", justify: "center", gap: 1, children: [
|
|
1061
1066
|
showLTV && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1062
1067
|
ui.Tooltip,
|
|
1063
1068
|
{
|
|
1064
1069
|
className: "oui-available-ltvRisk-tooltip oui-bg-base-6 oui-p-2",
|
|
1065
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipWidget, {}),
|
|
1070
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipWidget, { marginMode }),
|
|
1066
1071
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1067
1072
|
ui.InfoCircleIcon,
|
|
1068
1073
|
{
|
|
@@ -1154,9 +1159,15 @@ var OrderConfirmDialog = (props) => {
|
|
|
1154
1159
|
const { symbolInfo, order, onConfirm, onCancel } = props;
|
|
1155
1160
|
const { quote, quote_dp, base_dp } = symbolInfo;
|
|
1156
1161
|
const { side, order_type, order_type_ext, level, symbol } = order;
|
|
1162
|
+
const orderMarginMode = order.margin_mode;
|
|
1157
1163
|
const { t } = i18n.useTranslation();
|
|
1158
1164
|
const [{ rows: positions }] = hooks.usePositionStream(symbol);
|
|
1159
|
-
const position =
|
|
1165
|
+
const position = React3.useMemo(
|
|
1166
|
+
() => orderMarginMode != null ? positions?.find(
|
|
1167
|
+
(row) => row.symbol === symbol && row.margin_mode === orderMarginMode
|
|
1168
|
+
) : positions?.[0],
|
|
1169
|
+
[positions, symbol, orderMarginMode]
|
|
1170
|
+
);
|
|
1160
1171
|
const positionQty = position?.position_qty;
|
|
1161
1172
|
const [_, setNeedConfirm] = hooks.useLocalStorage("orderly_order_confirm", true);
|
|
1162
1173
|
const renderPositionType = () => {
|
|
@@ -1530,7 +1541,7 @@ var OrderItem = (props) => {
|
|
|
1530
1541
|
OrderConfirmDialog.displayName = "OrderConfirmDialog";
|
|
1531
1542
|
var OrderTypeTag = (props) => {
|
|
1532
1543
|
const { t } = i18n.useTranslation();
|
|
1533
|
-
const typeStr =
|
|
1544
|
+
const typeStr = React3.useMemo(() => {
|
|
1534
1545
|
switch (props.type) {
|
|
1535
1546
|
case types.OrderType.LIMIT:
|
|
1536
1547
|
return t("orderEntry.orderType.limit");
|
|
@@ -1570,7 +1581,7 @@ ui.registerSimpleDialog(orderConfirmDialogId, Dialog, {
|
|
|
1570
1581
|
size: "sm",
|
|
1571
1582
|
title: () => i18n.i18n.t("orderEntry.orderConfirm")
|
|
1572
1583
|
});
|
|
1573
|
-
var MaxQtyConfirm =
|
|
1584
|
+
var MaxQtyConfirm = React3.memo((props) => {
|
|
1574
1585
|
const { t } = i18n.useTranslation();
|
|
1575
1586
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1576
1587
|
ui.SimpleDialog,
|
|
@@ -1620,7 +1631,7 @@ var ScaledOrderConfirm = (props) => {
|
|
|
1620
1631
|
props.resolve();
|
|
1621
1632
|
props.close?.();
|
|
1622
1633
|
};
|
|
1623
|
-
const columns =
|
|
1634
|
+
const columns = React3.useMemo(() => {
|
|
1624
1635
|
return [
|
|
1625
1636
|
{
|
|
1626
1637
|
title: t("common.symbol"),
|
|
@@ -1782,7 +1793,7 @@ var ScaledOrderConfirm = (props) => {
|
|
|
1782
1793
|
] })
|
|
1783
1794
|
] });
|
|
1784
1795
|
};
|
|
1785
|
-
var TooltipIcon =
|
|
1796
|
+
var TooltipIcon = React3.forwardRef(
|
|
1786
1797
|
(props, ref) => {
|
|
1787
1798
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1788
1799
|
"svg",
|
|
@@ -1801,13 +1812,13 @@ var TooltipIcon = React2.forwardRef(
|
|
|
1801
1812
|
);
|
|
1802
1813
|
function useAskAndBid() {
|
|
1803
1814
|
const ee = hooks.useEventEmitter();
|
|
1804
|
-
const [askAndBid, setAskAndBid] =
|
|
1815
|
+
const [askAndBid, setAskAndBid] = React3.useState([0, 0]);
|
|
1805
1816
|
const onOrderBookUpdate = hooks.useDebouncedCallback((data) => {
|
|
1806
1817
|
const ask0 = data.asks?.[data.asks.length - 1]?.[0];
|
|
1807
1818
|
const bid0 = data.bids?.[0]?.[0];
|
|
1808
1819
|
setAskAndBid([ask0, bid0]);
|
|
1809
1820
|
}, 200);
|
|
1810
|
-
|
|
1821
|
+
React3.useEffect(() => {
|
|
1811
1822
|
ee.on("orderbook:update", onOrderBookUpdate);
|
|
1812
1823
|
return () => {
|
|
1813
1824
|
ee.off("orderbook:update", onOrderBookUpdate);
|
|
@@ -1822,13 +1833,13 @@ function useScaledOrderConfirmScript(options2) {
|
|
|
1822
1833
|
const { order, symbolInfo } = options2;
|
|
1823
1834
|
const orders = order.orders;
|
|
1824
1835
|
const askAndBid = useAskAndBid();
|
|
1825
|
-
const national =
|
|
1836
|
+
const national = React3.useMemo(() => {
|
|
1826
1837
|
const national2 = orders.reduce((acc, order2) => {
|
|
1827
1838
|
return acc.add(new utils.Decimal(order2.order_price).mul(order2.order_quantity));
|
|
1828
1839
|
}, utils.zero);
|
|
1829
1840
|
return national2.toNumber();
|
|
1830
1841
|
}, [orders]);
|
|
1831
|
-
const totalQuantity =
|
|
1842
|
+
const totalQuantity = React3.useMemo(() => {
|
|
1832
1843
|
const totalQuantity2 = orders.reduce((acc, order2) => {
|
|
1833
1844
|
return acc.add(new utils.Decimal(order2.order_quantity));
|
|
1834
1845
|
}, utils.zero);
|
|
@@ -1850,7 +1861,8 @@ ui.registerSimpleDialog(scaledOrderConfirmDialogId, ScaledOrderConfirmWidget, {
|
|
|
1850
1861
|
});
|
|
1851
1862
|
var OrderTypeSelect = (props) => {
|
|
1852
1863
|
const { t } = i18n.useTranslation();
|
|
1853
|
-
const
|
|
1864
|
+
const { isMobile } = ui.useScreen();
|
|
1865
|
+
const allOptions = React3.useMemo(() => {
|
|
1854
1866
|
return [
|
|
1855
1867
|
{ label: t("orderEntry.orderType.limitOrder"), value: types.OrderType.LIMIT },
|
|
1856
1868
|
{ label: t("orderEntry.orderType.marketOrder"), value: types.OrderType.MARKET },
|
|
@@ -1872,7 +1884,24 @@ var OrderTypeSelect = (props) => {
|
|
|
1872
1884
|
}
|
|
1873
1885
|
];
|
|
1874
1886
|
}, [t]);
|
|
1875
|
-
const
|
|
1887
|
+
const advancedOptions = React3.useMemo(() => {
|
|
1888
|
+
return [
|
|
1889
|
+
{
|
|
1890
|
+
label: t("orderEntry.orderType.stopLimit"),
|
|
1891
|
+
value: types.OrderType.STOP_LIMIT
|
|
1892
|
+
},
|
|
1893
|
+
{
|
|
1894
|
+
label: t("orderEntry.orderType.stopMarket"),
|
|
1895
|
+
value: types.OrderType.STOP_MARKET
|
|
1896
|
+
},
|
|
1897
|
+
{ label: t("orderEntry.orderType.scaledOrder"), value: types.OrderType.SCALED },
|
|
1898
|
+
{
|
|
1899
|
+
label: t("orderEntry.orderType.trailingStop"),
|
|
1900
|
+
value: types.OrderType.TRAILING_STOP
|
|
1901
|
+
}
|
|
1902
|
+
];
|
|
1903
|
+
}, [t]);
|
|
1904
|
+
const displayLabelMap = React3.useMemo(() => {
|
|
1876
1905
|
return {
|
|
1877
1906
|
[types.OrderType.LIMIT]: t("orderEntry.orderType.limit"),
|
|
1878
1907
|
[types.OrderType.MARKET]: t("common.marketPrice"),
|
|
@@ -1882,13 +1911,94 @@ var OrderTypeSelect = (props) => {
|
|
|
1882
1911
|
[types.OrderType.TRAILING_STOP]: t("orderEntry.orderType.trailingStop")
|
|
1883
1912
|
};
|
|
1884
1913
|
}, [t]);
|
|
1914
|
+
if (!isMobile) {
|
|
1915
|
+
const baseButtonClassName = "oui-flex oui-flex-1 oui-items-center oui-justify-center oui-gap-x-1 oui-rounded oui-px-3 oui-py-0.5 oui-text-xs oui-font-semibold oui-h-8";
|
|
1916
|
+
const selectedButtonClassName = ui.cn(
|
|
1917
|
+
baseButtonClassName,
|
|
1918
|
+
"oui-bg-base-5 oui-text-base-contrast"
|
|
1919
|
+
);
|
|
1920
|
+
const unselectedButtonClassName = ui.cn(
|
|
1921
|
+
baseButtonClassName,
|
|
1922
|
+
"oui-bg-base-7 oui-text-base-contrast-36"
|
|
1923
|
+
);
|
|
1924
|
+
const handleChange = (type) => {
|
|
1925
|
+
props.onChange(type);
|
|
1926
|
+
};
|
|
1927
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1928
|
+
"div",
|
|
1929
|
+
{
|
|
1930
|
+
className: "oui-flex oui-w-full oui-gap-1",
|
|
1931
|
+
"data-testid": "oui-testid-orderEntry-orderType-desktop",
|
|
1932
|
+
children: [
|
|
1933
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1934
|
+
"button",
|
|
1935
|
+
{
|
|
1936
|
+
type: "button",
|
|
1937
|
+
className: props.type === types.OrderType.LIMIT ? selectedButtonClassName : unselectedButtonClassName,
|
|
1938
|
+
"aria-pressed": props.type === types.OrderType.LIMIT,
|
|
1939
|
+
onClick: () => handleChange(types.OrderType.LIMIT),
|
|
1940
|
+
disabled: !props.canTrade,
|
|
1941
|
+
"data-testid": "oui-testid-orderEntry-orderType-limit",
|
|
1942
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.orderType.limit") })
|
|
1943
|
+
}
|
|
1944
|
+
),
|
|
1945
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1946
|
+
"button",
|
|
1947
|
+
{
|
|
1948
|
+
type: "button",
|
|
1949
|
+
className: props.type === types.OrderType.MARKET ? selectedButtonClassName : unselectedButtonClassName,
|
|
1950
|
+
"aria-pressed": props.type === types.OrderType.MARKET,
|
|
1951
|
+
onClick: () => handleChange(types.OrderType.MARKET),
|
|
1952
|
+
disabled: !props.canTrade,
|
|
1953
|
+
"data-testid": "oui-testid-orderEntry-orderType-market",
|
|
1954
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.orderType.market") })
|
|
1955
|
+
}
|
|
1956
|
+
),
|
|
1957
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1958
|
+
"div",
|
|
1959
|
+
{
|
|
1960
|
+
className: "oui-flex-1",
|
|
1961
|
+
"data-testid": "oui-testid-orderEntry-orderType-advanced",
|
|
1962
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1963
|
+
ui.Select.options,
|
|
1964
|
+
{
|
|
1965
|
+
testid: "oui-testid-orderEntry-orderType-advanced-select",
|
|
1966
|
+
currentValue: props.type,
|
|
1967
|
+
value: props.type,
|
|
1968
|
+
options: advancedOptions,
|
|
1969
|
+
onValueChange: props.onChange,
|
|
1970
|
+
placeholder: t("trading.layout.advanced"),
|
|
1971
|
+
disabled: !props.canTrade,
|
|
1972
|
+
contentProps: {
|
|
1973
|
+
className: "oui-bg-base-8"
|
|
1974
|
+
},
|
|
1975
|
+
classNames: {
|
|
1976
|
+
trigger: "oui-bg-base-7 oui-border-none oui-h-8 oui-rounded-md"
|
|
1977
|
+
},
|
|
1978
|
+
valueFormatter: (value, option) => {
|
|
1979
|
+
const isAdvanced = value === types.OrderType.STOP_LIMIT || value === types.OrderType.STOP_MARKET || value === types.OrderType.SCALED || value === types.OrderType.TRAILING_STOP;
|
|
1980
|
+
if (!isAdvanced) {
|
|
1981
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", className: "oui-text-base-contrast-80", children: option.placeholder });
|
|
1982
|
+
}
|
|
1983
|
+
const label = displayLabelMap[value];
|
|
1984
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", className: "oui-text-base-contrast-80", children: label });
|
|
1985
|
+
},
|
|
1986
|
+
size: "md"
|
|
1987
|
+
}
|
|
1988
|
+
)
|
|
1989
|
+
}
|
|
1990
|
+
)
|
|
1991
|
+
]
|
|
1992
|
+
}
|
|
1993
|
+
);
|
|
1994
|
+
}
|
|
1885
1995
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1886
1996
|
ui.Select.options,
|
|
1887
1997
|
{
|
|
1888
1998
|
testid: "oui-testid-orderEntry-orderType-button",
|
|
1889
1999
|
currentValue: props.type,
|
|
1890
2000
|
value: props.type,
|
|
1891
|
-
options:
|
|
2001
|
+
options: allOptions,
|
|
1892
2002
|
onValueChange: props.onChange,
|
|
1893
2003
|
contentProps: {
|
|
1894
2004
|
className: ui.cn(
|
|
@@ -1899,57 +2009,823 @@ var OrderTypeSelect = (props) => {
|
|
|
1899
2009
|
classNames: {
|
|
1900
2010
|
trigger: ui.cn(
|
|
1901
2011
|
"oui-orderEntry-orderTypeSelect-btn",
|
|
1902
|
-
"oui-bg-base-
|
|
2012
|
+
"oui-bg-base-7 oui-border-line-12 oui-h-8 oui-rounded-md"
|
|
1903
2013
|
)
|
|
1904
2014
|
},
|
|
1905
2015
|
valueFormatter: (value, option) => {
|
|
1906
|
-
const item =
|
|
2016
|
+
const item = allOptions.find((o) => o.value === value);
|
|
1907
2017
|
if (!item) {
|
|
1908
2018
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: option.placeholder });
|
|
1909
2019
|
}
|
|
1910
2020
|
const label = displayLabelMap[value];
|
|
1911
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1912
|
-
|
|
2021
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", className: "oui-text-base-contrast-80", children: label });
|
|
2022
|
+
},
|
|
2023
|
+
size: "md"
|
|
2024
|
+
}
|
|
2025
|
+
);
|
|
2026
|
+
};
|
|
2027
|
+
var MarginModeSwitch = (props) => {
|
|
2028
|
+
const { t } = i18n.useTranslation();
|
|
2029
|
+
const handleSelect = (mode) => {
|
|
2030
|
+
props.onSelect(mode);
|
|
2031
|
+
};
|
|
2032
|
+
const titleClassName = props.isMobile ? "oui-text-lg oui-leading-[26px]" : "oui-text-base oui-leading-6";
|
|
2033
|
+
const headerPadding = props.isMobile ? "oui-pt-3" : "oui-px-5 oui-pt-3";
|
|
2034
|
+
const contentPadding = props.isMobile ? "oui-py-4" : "oui-p-5";
|
|
2035
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2036
|
+
ui.Flex,
|
|
2037
|
+
{
|
|
2038
|
+
direction: "column",
|
|
2039
|
+
className: ui.cn(
|
|
2040
|
+
"oui-w-full",
|
|
2041
|
+
props.isMobile ? "oui-rounded-t-xl oui-bg-base-8" : "oui-rounded-xl oui-bg-base-8"
|
|
2042
|
+
),
|
|
2043
|
+
"data-testid": "oui-testid-marginModeSwitch",
|
|
2044
|
+
children: [
|
|
2045
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("oui-w-full", headerPadding), children: [
|
|
2046
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2047
|
+
ui.Flex,
|
|
2048
|
+
{
|
|
2049
|
+
itemAlign: "center",
|
|
2050
|
+
justify: "between",
|
|
2051
|
+
className: ui.cn(props.isMobile && "oui-px-4"),
|
|
2052
|
+
children: [
|
|
2053
|
+
props.isMobile ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2054
|
+
"button",
|
|
2055
|
+
{
|
|
2056
|
+
type: "button",
|
|
2057
|
+
className: "oui-size-[18px] oui-opacity-0",
|
|
2058
|
+
"aria-hidden": "true",
|
|
2059
|
+
tabIndex: -1
|
|
2060
|
+
}
|
|
2061
|
+
) : null,
|
|
2062
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2063
|
+
ui.Text,
|
|
2064
|
+
{
|
|
2065
|
+
className: ui.cn(
|
|
2066
|
+
"oui-font-semibold oui-tracking-[0.03em]",
|
|
2067
|
+
titleClassName
|
|
2068
|
+
),
|
|
2069
|
+
intensity: 98,
|
|
2070
|
+
children: t("marginMode.switchMarginMode")
|
|
2071
|
+
}
|
|
2072
|
+
),
|
|
2073
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2074
|
+
ui.IconButton,
|
|
2075
|
+
{
|
|
2076
|
+
color: "light",
|
|
2077
|
+
className: "oui-size-[18px]",
|
|
2078
|
+
onClick: props.close,
|
|
2079
|
+
"aria-label": "Close",
|
|
2080
|
+
"data-testid": "oui-testid-marginModeSwitch-close",
|
|
2081
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: 18, color: "white", opacity: 0.98 })
|
|
2082
|
+
}
|
|
2083
|
+
)
|
|
2084
|
+
]
|
|
2085
|
+
}
|
|
2086
|
+
),
|
|
2087
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-mt-[9px] oui-w-full" })
|
|
2088
|
+
] }),
|
|
2089
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2090
|
+
"div",
|
|
1913
2091
|
{
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
2092
|
+
className: ui.cn(
|
|
2093
|
+
"oui-w-full",
|
|
2094
|
+
contentPadding,
|
|
2095
|
+
props.isMobile && "oui-px-4"
|
|
2096
|
+
),
|
|
2097
|
+
children: [
|
|
2098
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { itemAlign: "center", gap: 2, children: [
|
|
2099
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: props.symbol, className: "oui-size-5" }),
|
|
2100
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2101
|
+
ui.Text.formatted,
|
|
2102
|
+
{
|
|
2103
|
+
className: "oui-tracking-[0.03em]",
|
|
2104
|
+
rule: "symbol",
|
|
2105
|
+
formatString: "base-type",
|
|
2106
|
+
size: "base",
|
|
2107
|
+
weight: "semibold",
|
|
2108
|
+
intensity: 98,
|
|
2109
|
+
children: props.symbol
|
|
2110
|
+
}
|
|
2111
|
+
)
|
|
2112
|
+
] }),
|
|
2113
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 3, className: "oui-mt-3 oui-w-full", children: [
|
|
2114
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2115
|
+
OptionCard,
|
|
2116
|
+
{
|
|
2117
|
+
mode: types.MarginMode.CROSS,
|
|
2118
|
+
selected: props.selectedMarginMode === types.MarginMode.CROSS,
|
|
2119
|
+
isCurrent: props.currentMarginMode === types.MarginMode.CROSS,
|
|
2120
|
+
onClick: () => handleSelect(types.MarginMode.CROSS)
|
|
2121
|
+
}
|
|
2122
|
+
),
|
|
2123
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2124
|
+
OptionCard,
|
|
2125
|
+
{
|
|
2126
|
+
mode: types.MarginMode.ISOLATED,
|
|
2127
|
+
selected: props.selectedMarginMode === types.MarginMode.ISOLATED,
|
|
2128
|
+
isCurrent: props.currentMarginMode === types.MarginMode.ISOLATED,
|
|
2129
|
+
onClick: () => handleSelect(types.MarginMode.ISOLATED)
|
|
2130
|
+
}
|
|
2131
|
+
)
|
|
2132
|
+
] }),
|
|
2133
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { justify: "center", className: "oui-mt-3 oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2134
|
+
"button",
|
|
2135
|
+
{
|
|
2136
|
+
type: "button",
|
|
2137
|
+
className: ui.cn(
|
|
2138
|
+
"oui-flex oui-items-center oui-gap-1",
|
|
2139
|
+
"oui-group",
|
|
2140
|
+
"oui-text-xs oui-leading-[15px] oui-font-semibold oui-text-base-contrast-54 oui-tracking-[0.03em]",
|
|
2141
|
+
props.onOpenSettings ? "oui-cursor-pointer hover:oui-text-base-contrast-80 oui-transition-colors" : "oui-cursor-default"
|
|
2142
|
+
),
|
|
2143
|
+
onClick: props.onOpenSettings,
|
|
2144
|
+
disabled: !props.onOpenSettings,
|
|
2145
|
+
"data-testid": "oui-testid-marginModeSwitch-settings",
|
|
2146
|
+
children: [
|
|
2147
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t("marginMode.marginModeSettings") }),
|
|
2148
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2149
|
+
ui.ChevronRightIcon,
|
|
2150
|
+
{
|
|
2151
|
+
size: 18,
|
|
2152
|
+
color: "white",
|
|
2153
|
+
opacity: 1,
|
|
2154
|
+
className: ui.cn(
|
|
2155
|
+
"oui-text-base-contrast-54 oui-transition-colors",
|
|
2156
|
+
props.onOpenSettings && "group-hover:oui-text-base-contrast-80"
|
|
2157
|
+
)
|
|
2158
|
+
}
|
|
2159
|
+
)
|
|
2160
|
+
]
|
|
2161
|
+
}
|
|
2162
|
+
) }),
|
|
2163
|
+
props.isMobile ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-mt-4 oui-h-[34px] oui-w-full" }) : null
|
|
2164
|
+
]
|
|
2165
|
+
}
|
|
2166
|
+
)
|
|
2167
|
+
]
|
|
2168
|
+
}
|
|
2169
|
+
);
|
|
2170
|
+
};
|
|
2171
|
+
var OptionCard = (props) => {
|
|
2172
|
+
const { t } = i18n.useTranslation();
|
|
2173
|
+
const title = props.mode === types.MarginMode.CROSS ? t("marginMode.crossMargin") : t("marginMode.isolatedMargin");
|
|
2174
|
+
const desc = props.mode === types.MarginMode.CROSS ? t("marginMode.crossMarginDescription") : t("marginMode.isolatedMarginDescription");
|
|
2175
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2176
|
+
"button",
|
|
2177
|
+
{
|
|
2178
|
+
type: "button",
|
|
2179
|
+
className: ui.cn(
|
|
2180
|
+
"oui-relative oui-w-full oui-rounded-md oui-p-2",
|
|
2181
|
+
"oui-bg-base-6",
|
|
2182
|
+
"oui-text-left",
|
|
2183
|
+
props.selected ? "oui-border oui-border-[#38e2fe]" : "oui-border oui-border-transparent hover:oui-border-line-12"
|
|
2184
|
+
),
|
|
2185
|
+
onClick: props.onClick,
|
|
2186
|
+
"data-testid": `oui-testid-marginModeSwitch-option-${props.mode}`,
|
|
2187
|
+
children: [
|
|
2188
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 2, itemAlign: "start", className: "oui-w-full", children: [
|
|
2189
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2190
|
+
ui.Text,
|
|
2191
|
+
{
|
|
2192
|
+
className: "oui-text-sm oui-font-semibold oui-leading-5 oui-tracking-[0.03em]",
|
|
2193
|
+
intensity: 98,
|
|
2194
|
+
children: title
|
|
2195
|
+
}
|
|
2196
|
+
),
|
|
2197
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-2xs oui-leading-[15px] oui-text-base-contrast-36 oui-font-semibold oui-tracking-[0.03em]", children: desc })
|
|
2198
|
+
] }),
|
|
2199
|
+
props.isCurrent ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2200
|
+
"div",
|
|
2201
|
+
{
|
|
2202
|
+
className: ui.cn(
|
|
2203
|
+
"oui-absolute -oui-right-px -oui-top-px",
|
|
2204
|
+
"oui-rounded-bl-md oui-rounded-tr-md",
|
|
2205
|
+
"oui-bg-[#38e2fe] oui-px-1 oui-py-0.5"
|
|
2206
|
+
),
|
|
2207
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-2xs oui-leading-none oui-font-semibold oui-text-black", children: t("marginMode.current") })
|
|
1917
2208
|
}
|
|
2209
|
+
) : null
|
|
2210
|
+
]
|
|
2211
|
+
}
|
|
2212
|
+
);
|
|
2213
|
+
};
|
|
2214
|
+
var useMarginModeSwitchScript = (options2) => {
|
|
2215
|
+
const { symbol, close } = options2;
|
|
2216
|
+
const { isMobile } = ui.useScreen();
|
|
2217
|
+
const { t } = i18n.useTranslation();
|
|
2218
|
+
const { marginMode: currentMarginMode, update } = hooks.useMarginModeBySymbol(symbol);
|
|
2219
|
+
const [selectedMarginMode, setSelectedMarginMode] = React3.useState(currentMarginMode);
|
|
2220
|
+
React3.useEffect(() => {
|
|
2221
|
+
setSelectedMarginMode(currentMarginMode);
|
|
2222
|
+
}, [currentMarginMode]);
|
|
2223
|
+
const applyMarginMode = React3.useCallback(
|
|
2224
|
+
async (mode) => {
|
|
2225
|
+
const result = await update(mode);
|
|
2226
|
+
setSelectedMarginMode(mode);
|
|
2227
|
+
return result;
|
|
2228
|
+
},
|
|
2229
|
+
[update]
|
|
2230
|
+
);
|
|
2231
|
+
const onSelect = React3.useCallback(
|
|
2232
|
+
(mode) => {
|
|
2233
|
+
if (mode === currentMarginMode) {
|
|
2234
|
+
close?.();
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
close?.();
|
|
2238
|
+
applyMarginMode(mode).then(() => {
|
|
2239
|
+
ui.toast.success(t("marginMode.updatedSuccessfully"));
|
|
2240
|
+
}).catch((error) => {
|
|
2241
|
+
ui.toast.error(
|
|
2242
|
+
error instanceof Error ? error.message : "Failed to update margin mode"
|
|
1918
2243
|
);
|
|
1919
|
-
}
|
|
1920
|
-
|
|
2244
|
+
});
|
|
2245
|
+
},
|
|
2246
|
+
[applyMarginMode, close, currentMarginMode, t]
|
|
2247
|
+
);
|
|
2248
|
+
return {
|
|
2249
|
+
symbol,
|
|
2250
|
+
isMobile,
|
|
2251
|
+
currentMarginMode,
|
|
2252
|
+
selectedMarginMode,
|
|
2253
|
+
setSelectedMarginMode,
|
|
2254
|
+
applyMarginMode,
|
|
2255
|
+
close,
|
|
2256
|
+
onSelect
|
|
2257
|
+
};
|
|
2258
|
+
};
|
|
2259
|
+
var useMarginModeSettingsScript = (options2) => {
|
|
2260
|
+
const { isMobile } = ui.useScreen();
|
|
2261
|
+
const [markets] = hooks.useMarkets(hooks.MarketsType.ALL);
|
|
2262
|
+
const items = React3.useMemo(() => {
|
|
2263
|
+
if (!markets || markets.length === 0) {
|
|
2264
|
+
return [];
|
|
2265
|
+
}
|
|
2266
|
+
return markets.map((market) => ({
|
|
2267
|
+
key: market.symbol,
|
|
2268
|
+
// Original symbol: "PERP_BTC_USDC"
|
|
2269
|
+
symbol: utils.formatSymbol(market.symbol, "base-type")
|
|
2270
|
+
// Formatted: "BTC-PERP"
|
|
2271
|
+
}));
|
|
2272
|
+
}, [markets]);
|
|
2273
|
+
const [searchKeyword, setSearchKeyword] = React3.useState("");
|
|
2274
|
+
const [selectedKeys, setSelectedKeys] = React3.useState(
|
|
2275
|
+
() => /* @__PURE__ */ new Set()
|
|
2276
|
+
);
|
|
2277
|
+
const [isOperationLoading, setIsOperationLoading] = React3.useState(false);
|
|
2278
|
+
const {
|
|
2279
|
+
marginModes,
|
|
2280
|
+
isLoading: isMarginModesLoading,
|
|
2281
|
+
updateMarginMode,
|
|
2282
|
+
isMutating: isSettingMarginMode
|
|
2283
|
+
} = hooks.useMarginModes();
|
|
2284
|
+
const [isDataLoading, setIsDataLoading] = React3.useState(true);
|
|
2285
|
+
React3.useEffect(() => {
|
|
2286
|
+
if (markets.length > 0) {
|
|
2287
|
+
setIsDataLoading(false);
|
|
2288
|
+
}
|
|
2289
|
+
}, [markets]);
|
|
2290
|
+
const itemMarginModes = React3.useMemo(() => {
|
|
2291
|
+
const result = {};
|
|
2292
|
+
for (const item of items) {
|
|
2293
|
+
const marginMode = marginModes[item.key];
|
|
2294
|
+
result[item.key] = marginMode ?? types.MarginMode.CROSS;
|
|
2295
|
+
}
|
|
2296
|
+
return result;
|
|
2297
|
+
}, [items, marginModes]);
|
|
2298
|
+
const filteredItems = React3.useMemo(() => {
|
|
2299
|
+
const keyword = searchKeyword.trim().toLowerCase();
|
|
2300
|
+
if (!keyword) return items;
|
|
2301
|
+
return items.filter((item) => item.symbol.toLowerCase().includes(keyword));
|
|
2302
|
+
}, [items, searchKeyword]);
|
|
2303
|
+
const visibleSelectedCount = React3.useMemo(() => {
|
|
2304
|
+
return filteredItems.filter((item) => selectedKeys.has(item.key)).length;
|
|
2305
|
+
}, [filteredItems, selectedKeys]);
|
|
2306
|
+
const isSelectAll = React3.useMemo(() => {
|
|
2307
|
+
return filteredItems.length > 0 && visibleSelectedCount === filteredItems.length;
|
|
2308
|
+
}, [filteredItems.length, visibleSelectedCount]);
|
|
2309
|
+
const isIndeterminate = React3.useMemo(() => {
|
|
2310
|
+
return visibleSelectedCount > 0 && visibleSelectedCount < filteredItems.length;
|
|
2311
|
+
}, [filteredItems.length, visibleSelectedCount]);
|
|
2312
|
+
const selectedMarginModeStats = React3.useMemo(() => {
|
|
2313
|
+
let crossCount = 0;
|
|
2314
|
+
let isolatedCount = 0;
|
|
2315
|
+
selectedKeys.forEach((key) => {
|
|
2316
|
+
const mode = itemMarginModes[key] ?? types.MarginMode.CROSS;
|
|
2317
|
+
if (mode === types.MarginMode.CROSS) {
|
|
2318
|
+
crossCount++;
|
|
2319
|
+
} else {
|
|
2320
|
+
isolatedCount++;
|
|
2321
|
+
}
|
|
2322
|
+
});
|
|
2323
|
+
return {
|
|
2324
|
+
crossCount,
|
|
2325
|
+
isolatedCount,
|
|
2326
|
+
isCrossButtonDisabled: crossCount > 0 && isolatedCount === 0,
|
|
2327
|
+
isIsolatedButtonDisabled: isolatedCount > 0 && crossCount === 0
|
|
2328
|
+
};
|
|
2329
|
+
}, [selectedKeys, itemMarginModes]);
|
|
2330
|
+
const onSearchChange = React3.useCallback((keyword) => {
|
|
2331
|
+
setSearchKeyword(keyword);
|
|
2332
|
+
}, []);
|
|
2333
|
+
const onToggleItem = React3.useCallback((key) => {
|
|
2334
|
+
setSelectedKeys((prev) => {
|
|
2335
|
+
const next = new Set(prev);
|
|
2336
|
+
if (next.has(key)) {
|
|
2337
|
+
next.delete(key);
|
|
2338
|
+
} else {
|
|
2339
|
+
next.add(key);
|
|
2340
|
+
}
|
|
2341
|
+
return next;
|
|
2342
|
+
});
|
|
2343
|
+
}, []);
|
|
2344
|
+
const onToggleSelectAll = React3.useCallback(() => {
|
|
2345
|
+
setSelectedKeys((prev) => {
|
|
2346
|
+
const next = new Set(prev);
|
|
2347
|
+
if (isSelectAll) {
|
|
2348
|
+
for (const item of filteredItems) {
|
|
2349
|
+
next.delete(item.key);
|
|
2350
|
+
}
|
|
2351
|
+
return next;
|
|
2352
|
+
}
|
|
2353
|
+
for (const item of filteredItems) {
|
|
2354
|
+
next.add(item.key);
|
|
2355
|
+
}
|
|
2356
|
+
return next;
|
|
2357
|
+
});
|
|
2358
|
+
}, [filteredItems, isSelectAll]);
|
|
2359
|
+
const onSetMarginMode = React3.useCallback(
|
|
2360
|
+
async (mode) => {
|
|
2361
|
+
if (selectedKeys.size === 0) return;
|
|
2362
|
+
setIsOperationLoading(true);
|
|
2363
|
+
try {
|
|
2364
|
+
const payload = {
|
|
2365
|
+
symbol_list: Array.from(selectedKeys),
|
|
2366
|
+
default_margin_mode: mode
|
|
2367
|
+
};
|
|
2368
|
+
await updateMarginMode(payload);
|
|
2369
|
+
ui.toast.success("Updated successfully");
|
|
2370
|
+
} catch (error) {
|
|
2371
|
+
ui.toast.error(
|
|
2372
|
+
error instanceof Error ? error.message : "Failed to update margin mode"
|
|
2373
|
+
);
|
|
2374
|
+
} finally {
|
|
2375
|
+
setIsOperationLoading(false);
|
|
2376
|
+
}
|
|
2377
|
+
},
|
|
2378
|
+
[selectedKeys, updateMarginMode]
|
|
2379
|
+
);
|
|
2380
|
+
const isLoading = isDataLoading || isMarginModesLoading || isOperationLoading || isSettingMarginMode;
|
|
2381
|
+
return {
|
|
2382
|
+
isMobile,
|
|
2383
|
+
close: options2.close,
|
|
2384
|
+
items,
|
|
2385
|
+
filteredItems,
|
|
2386
|
+
searchKeyword,
|
|
2387
|
+
selectedKeys,
|
|
2388
|
+
itemMarginModes,
|
|
2389
|
+
isSelectAll,
|
|
2390
|
+
isIndeterminate,
|
|
2391
|
+
isLoading,
|
|
2392
|
+
isCrossButtonDisabled: selectedMarginModeStats.isCrossButtonDisabled,
|
|
2393
|
+
isIsolatedButtonDisabled: selectedMarginModeStats.isIsolatedButtonDisabled,
|
|
2394
|
+
onSearchChange,
|
|
2395
|
+
onToggleItem,
|
|
2396
|
+
onToggleSelectAll,
|
|
2397
|
+
onSetMarginMode
|
|
2398
|
+
};
|
|
2399
|
+
};
|
|
2400
|
+
var MarginModeSettings = (props) => {
|
|
2401
|
+
const { t } = i18n.useTranslation();
|
|
2402
|
+
const headerPadding = props.isMobile ? "oui-px-4 oui-pt-3" : "oui-px-5 oui-pt-3";
|
|
2403
|
+
const contentPadding = props.isMobile ? "oui-px-4" : "oui-px-5";
|
|
2404
|
+
const selectedCount = props.selectedKeys.size;
|
|
2405
|
+
const totalCountTextClassName = selectedCount > 0 ? "oui-text-primary-light" : "oui-text-base-contrast-36";
|
|
2406
|
+
const handleClearSearch = React3.useCallback(() => {
|
|
2407
|
+
props.onSearchChange("");
|
|
2408
|
+
}, [props.onSearchChange]);
|
|
2409
|
+
const handleSetCross = React3.useCallback(() => {
|
|
2410
|
+
props.onSetMarginMode(types.MarginMode.CROSS);
|
|
2411
|
+
}, [props.onSetMarginMode]);
|
|
2412
|
+
const handleSetIsolated = React3.useCallback(() => {
|
|
2413
|
+
props.onSetMarginMode(types.MarginMode.ISOLATED);
|
|
2414
|
+
}, [props.onSetMarginMode]);
|
|
2415
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2416
|
+
ui.Flex,
|
|
2417
|
+
{
|
|
2418
|
+
direction: "column",
|
|
2419
|
+
className: ui.cn(
|
|
2420
|
+
"oui-size-full",
|
|
2421
|
+
"oui-rounded-xl oui-bg-base-8",
|
|
2422
|
+
"oui-overflow-hidden"
|
|
2423
|
+
),
|
|
2424
|
+
"data-testid": "oui-testid-marginModeSettings",
|
|
2425
|
+
children: [
|
|
2426
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("oui-w-full", headerPadding), children: [
|
|
2427
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { itemAlign: "center", justify: "between", children: [
|
|
2428
|
+
props.isMobile ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2429
|
+
"button",
|
|
2430
|
+
{
|
|
2431
|
+
type: "button",
|
|
2432
|
+
className: "oui-size-[18px] oui-opacity-0",
|
|
2433
|
+
"aria-hidden": "true",
|
|
2434
|
+
tabIndex: -1
|
|
2435
|
+
}
|
|
2436
|
+
) : null,
|
|
2437
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2438
|
+
ui.Text,
|
|
2439
|
+
{
|
|
2440
|
+
className: ui.cn(
|
|
2441
|
+
"oui-font-semibold oui-tracking-[0.48px]",
|
|
2442
|
+
props.isMobile ? "oui-text-center oui-text-lg oui-leading-[26px]" : "oui-text-base oui-leading-6"
|
|
2443
|
+
),
|
|
2444
|
+
intensity: 98,
|
|
2445
|
+
children: t("marginMode.perpetualFutures")
|
|
2446
|
+
}
|
|
2447
|
+
),
|
|
2448
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2449
|
+
ui.IconButton,
|
|
2450
|
+
{
|
|
2451
|
+
color: "light",
|
|
2452
|
+
className: "oui-size-[18px]",
|
|
2453
|
+
onClick: props.close,
|
|
2454
|
+
"aria-label": t("common.close"),
|
|
2455
|
+
"data-testid": "oui-testid-marginModeSettings-close",
|
|
2456
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: 18, color: "white", opacity: 0.98 })
|
|
2457
|
+
}
|
|
2458
|
+
)
|
|
2459
|
+
] }),
|
|
2460
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-mt-[9px] oui-w-full" })
|
|
2461
|
+
] }),
|
|
2462
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2463
|
+
"div",
|
|
2464
|
+
{
|
|
2465
|
+
className: ui.cn(
|
|
2466
|
+
"oui-relative oui-z-10 oui-w-full oui-bg-base-8",
|
|
2467
|
+
contentPadding,
|
|
2468
|
+
"oui-py-3"
|
|
2469
|
+
),
|
|
2470
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2471
|
+
ui.Input,
|
|
2472
|
+
{
|
|
2473
|
+
value: props.searchKeyword,
|
|
2474
|
+
onValueChange: props.onSearchChange,
|
|
2475
|
+
placeholder: t("marginMode.searchPlaceholder"),
|
|
2476
|
+
size: "md",
|
|
2477
|
+
fullWidth: true,
|
|
2478
|
+
classNames: {
|
|
2479
|
+
root: ui.cn(
|
|
2480
|
+
"oui-outline-line",
|
|
2481
|
+
props.searchKeyword.trim() ? "oui-outline-primary-light" : ""
|
|
2482
|
+
)
|
|
2483
|
+
},
|
|
2484
|
+
prefix: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-pl-3 oui-pr-1", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(SearchGlyph, { className: "oui-text-base-contrast-54" }) }),
|
|
2485
|
+
suffix: props.searchKeyword ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-pr-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2486
|
+
ui.CloseCircleFillIcon,
|
|
2487
|
+
{
|
|
2488
|
+
size: 14,
|
|
2489
|
+
className: "oui-cursor-pointer oui-text-base-contrast-36",
|
|
2490
|
+
onClick: handleClearSearch
|
|
2491
|
+
}
|
|
2492
|
+
) }) : null,
|
|
2493
|
+
autoComplete: "off"
|
|
2494
|
+
}
|
|
2495
|
+
)
|
|
2496
|
+
}
|
|
2497
|
+
),
|
|
2498
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2499
|
+
ui.Flex,
|
|
2500
|
+
{
|
|
2501
|
+
direction: "column",
|
|
2502
|
+
className: ui.cn(
|
|
2503
|
+
"oui-w-full",
|
|
2504
|
+
props.isMobile ? "oui-flex-1 oui-min-h-0" : ""
|
|
2505
|
+
),
|
|
2506
|
+
children: [
|
|
2507
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2508
|
+
ui.Flex,
|
|
2509
|
+
{
|
|
2510
|
+
direction: "column",
|
|
2511
|
+
gap: 3,
|
|
2512
|
+
className: ui.cn(
|
|
2513
|
+
"oui-w-full oui-overflow-y-auto oui-custom-scrollbar",
|
|
2514
|
+
props.isMobile ? "oui-flex-1 oui-min-h-0 oui-px-4 oui-pt-0 oui-pb-3" : "oui-h-[308px] oui-px-5 oui-pt-0 oui-pb-3"
|
|
2515
|
+
),
|
|
2516
|
+
style: {
|
|
2517
|
+
scrollbarWidth: "thin",
|
|
2518
|
+
scrollbarColor: "rgba(255, 255, 255, 0.2) transparent"
|
|
2519
|
+
},
|
|
2520
|
+
children: props.filteredItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2521
|
+
SymbolRow,
|
|
2522
|
+
{
|
|
2523
|
+
item,
|
|
2524
|
+
checked: props.selectedKeys.has(item.key),
|
|
2525
|
+
marginMode: props.itemMarginModes[item.key] ?? types.MarginMode.CROSS,
|
|
2526
|
+
onToggle: props.onToggleItem
|
|
2527
|
+
},
|
|
2528
|
+
item.key
|
|
2529
|
+
))
|
|
2530
|
+
}
|
|
2531
|
+
),
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
|
|
2533
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2534
|
+
ui.Flex,
|
|
2535
|
+
{
|
|
2536
|
+
itemAlign: "center",
|
|
2537
|
+
justify: "between",
|
|
2538
|
+
className: ui.cn(
|
|
2539
|
+
"oui-w-full",
|
|
2540
|
+
props.isMobile ? "oui-px-4 oui-py-3" : "oui-px-5 oui-py-3"
|
|
2541
|
+
),
|
|
2542
|
+
children: [
|
|
2543
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { itemAlign: "center", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2544
|
+
"label",
|
|
2545
|
+
{
|
|
2546
|
+
className: ui.cn(
|
|
2547
|
+
"oui-flex oui-items-center oui-gap-2 oui-cursor-pointer oui-select-none"
|
|
2548
|
+
),
|
|
2549
|
+
children: [
|
|
2550
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2551
|
+
ui.Checkbox,
|
|
2552
|
+
{
|
|
2553
|
+
color: "white",
|
|
2554
|
+
checked: props.isSelectAll,
|
|
2555
|
+
onCheckedChange: () => {
|
|
2556
|
+
props.onToggleSelectAll();
|
|
2557
|
+
},
|
|
2558
|
+
"aria-label": t("marginMode.selectAll")
|
|
2559
|
+
}
|
|
2560
|
+
),
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-sm oui-font-semibold oui-text-base-contrast-80", children: t("marginMode.selectAll") })
|
|
2562
|
+
]
|
|
2563
|
+
}
|
|
2564
|
+
) }),
|
|
2565
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-text-sm oui-text-base-contrast-54", children: [
|
|
2566
|
+
t("common.total"),
|
|
2567
|
+
":",
|
|
2568
|
+
" ",
|
|
2569
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn("oui-font-semibold", totalCountTextClassName), children: selectedCount })
|
|
2570
|
+
] })
|
|
2571
|
+
]
|
|
2572
|
+
}
|
|
2573
|
+
),
|
|
2574
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2575
|
+
ui.Flex,
|
|
2576
|
+
{
|
|
2577
|
+
itemAlign: "center",
|
|
2578
|
+
justify: "end",
|
|
2579
|
+
gap: 3,
|
|
2580
|
+
className: ui.cn(
|
|
2581
|
+
"oui-w-full",
|
|
2582
|
+
props.isMobile ? "oui-px-4 oui-pt-3 oui-pb-[calc(20px+env(safe-area-inset-bottom))]" : "oui-px-5 oui-pt-3 oui-pb-5"
|
|
2583
|
+
),
|
|
2584
|
+
children: [
|
|
2585
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-sm oui-leading-8 oui-text-base-contrast-80", children: t("marginMode.setAs") }),
|
|
2586
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2587
|
+
ui.Button,
|
|
2588
|
+
{
|
|
2589
|
+
size: "md",
|
|
2590
|
+
className: ui.cn(
|
|
2591
|
+
"oui-bg-base-3 hover:oui-bg-base-3/80 active:oui-bg-base-3/70",
|
|
2592
|
+
selectedCount > 0 && !props.isLoading ? "oui-text-base-contrast-80" : "oui-text-base-contrast-98"
|
|
2593
|
+
),
|
|
2594
|
+
disabled: selectedCount === 0 || props.isLoading || (props.isCrossButtonDisabled ?? false),
|
|
2595
|
+
onClick: handleSetCross,
|
|
2596
|
+
"aria-label": t("marginMode.cross"),
|
|
2597
|
+
"data-testid": "oui-testid-marginModeSettings-set-cross",
|
|
2598
|
+
children: t("marginMode.cross")
|
|
2599
|
+
}
|
|
2600
|
+
),
|
|
2601
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2602
|
+
ui.Button,
|
|
2603
|
+
{
|
|
2604
|
+
size: "md",
|
|
2605
|
+
className: ui.cn(
|
|
2606
|
+
"oui-bg-base-3 hover:oui-bg-base-3/80 active:oui-bg-base-3/70",
|
|
2607
|
+
selectedCount > 0 && !props.isLoading ? "oui-text-base-contrast-80" : "oui-text-base-contrast-98"
|
|
2608
|
+
),
|
|
2609
|
+
disabled: selectedCount === 0 || props.isLoading || (props.isIsolatedButtonDisabled ?? false),
|
|
2610
|
+
onClick: handleSetIsolated,
|
|
2611
|
+
"aria-label": t("marginMode.isolated"),
|
|
2612
|
+
"data-testid": "oui-testid-marginModeSettings-set-isolated",
|
|
2613
|
+
children: t("marginMode.isolated")
|
|
2614
|
+
}
|
|
2615
|
+
)
|
|
2616
|
+
]
|
|
2617
|
+
}
|
|
2618
|
+
)
|
|
2619
|
+
]
|
|
2620
|
+
}
|
|
2621
|
+
)
|
|
2622
|
+
]
|
|
1921
2623
|
}
|
|
1922
2624
|
);
|
|
1923
2625
|
};
|
|
2626
|
+
var SymbolRow = (props) => {
|
|
2627
|
+
const { t } = i18n.useTranslation();
|
|
2628
|
+
const handleCheckedChange = React3.useCallback(() => {
|
|
2629
|
+
props.onToggle(props.item.key);
|
|
2630
|
+
}, [props]);
|
|
2631
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { itemAlign: "center", className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2632
|
+
"label",
|
|
2633
|
+
{
|
|
2634
|
+
className: ui.cn(
|
|
2635
|
+
"oui-flex oui-items-center oui-gap-2 oui-flex-1 oui-cursor-pointer oui-select-none oui-w-full"
|
|
2636
|
+
),
|
|
2637
|
+
"data-testid": `oui-testid-marginModeSettings-item-${props.item.key}`,
|
|
2638
|
+
children: [
|
|
2639
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2640
|
+
ui.Checkbox,
|
|
2641
|
+
{
|
|
2642
|
+
color: "white",
|
|
2643
|
+
checked: props.checked,
|
|
2644
|
+
onCheckedChange: handleCheckedChange,
|
|
2645
|
+
"aria-label": props.item.symbol
|
|
2646
|
+
}
|
|
2647
|
+
),
|
|
2648
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-sm oui-font-semibold oui-text-base-contrast-80", children: props.item.symbol }),
|
|
2649
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2650
|
+
"span",
|
|
2651
|
+
{
|
|
2652
|
+
className: ui.cn(
|
|
2653
|
+
"oui-inline-flex oui-items-center",
|
|
2654
|
+
"oui-rounded oui-bg-base-6 oui-px-2 oui-py-0",
|
|
2655
|
+
"oui-h-[18px] oui-text-xs oui-leading-[18px]",
|
|
2656
|
+
"oui-text-base-contrast-36"
|
|
2657
|
+
),
|
|
2658
|
+
children: props.marginMode === types.MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross")
|
|
2659
|
+
}
|
|
2660
|
+
)
|
|
2661
|
+
]
|
|
2662
|
+
}
|
|
2663
|
+
) });
|
|
2664
|
+
};
|
|
2665
|
+
var SearchGlyph = (props) => {
|
|
2666
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2667
|
+
"svg",
|
|
2668
|
+
{
|
|
2669
|
+
width: "14",
|
|
2670
|
+
height: "14",
|
|
2671
|
+
viewBox: "0 0 14 14",
|
|
2672
|
+
fill: "none",
|
|
2673
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2674
|
+
className: props.className,
|
|
2675
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2676
|
+
"path",
|
|
2677
|
+
{
|
|
2678
|
+
d: "M6.417 1.167a5.25 5.25 0 1 0 3.138 9.46l2.139 2.14a.583.583 0 1 0 .825-.826l-2.14-2.139a5.25 5.25 0 0 0-3.962-8.635Zm0 1.167a4.083 4.083 0 1 1 0 8.166 4.083 4.083 0 0 1 0-8.166Z",
|
|
2679
|
+
fill: "currentColor",
|
|
2680
|
+
fillOpacity: "0.8"
|
|
2681
|
+
}
|
|
2682
|
+
)
|
|
2683
|
+
}
|
|
2684
|
+
);
|
|
2685
|
+
};
|
|
2686
|
+
var MarginModeSettingsWidget = (props) => {
|
|
2687
|
+
const state = useMarginModeSettingsScript(props);
|
|
2688
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MarginModeSettings, { ...state, onSetMarginMode: state.onSetMarginMode });
|
|
2689
|
+
};
|
|
2690
|
+
var MarginModeSettingsSheetId = "MarginModeSettingsSheetId";
|
|
2691
|
+
var MarginModeSettingsDialogId = "MarginModeSettingsDialogId";
|
|
2692
|
+
ui.registerSimpleSheet(MarginModeSettingsSheetId, MarginModeSettingsWidget, {
|
|
2693
|
+
title: void 0,
|
|
2694
|
+
closable: false,
|
|
2695
|
+
classNames: {
|
|
2696
|
+
content: "oui-bg-transparent !oui-px-0 !oui-py-0 oui-top-[100px] oui-bottom-0",
|
|
2697
|
+
// SheetBody must be full height, otherwise child `h-full`/flex layout can't allocate space
|
|
2698
|
+
// and footer may be pushed out of viewport.
|
|
2699
|
+
body: "oui-p-0 oui-h-full",
|
|
2700
|
+
overlay: "!oui-bg-black/10"
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
ui.registerSimpleDialog(MarginModeSettingsDialogId, MarginModeSettingsWidget, {
|
|
2704
|
+
title: void 0,
|
|
2705
|
+
closable: false,
|
|
2706
|
+
classNames: {
|
|
2707
|
+
content: "oui-w-[360px] oui-bg-transparent !oui-px-0",
|
|
2708
|
+
body: "oui-p-0",
|
|
2709
|
+
overlay: "!oui-bg-black/10"
|
|
2710
|
+
}
|
|
2711
|
+
});
|
|
2712
|
+
var MarginModeSwitchWidget = (props) => {
|
|
2713
|
+
const state = useMarginModeSwitchScript(props);
|
|
2714
|
+
const { id: currentModalId } = ui.useModal();
|
|
2715
|
+
const onOpenSettings = () => {
|
|
2716
|
+
const modalId = currentModalId === MarginModeSwitchSheetId ? MarginModeSettingsSheetId : MarginModeSettingsDialogId;
|
|
2717
|
+
ui.modal.show(modalId, {});
|
|
2718
|
+
};
|
|
2719
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2720
|
+
MarginModeSwitch,
|
|
2721
|
+
{
|
|
2722
|
+
...state,
|
|
2723
|
+
onOpenSettings: props.onOpenSettings ?? onOpenSettings
|
|
2724
|
+
}
|
|
2725
|
+
);
|
|
2726
|
+
};
|
|
2727
|
+
var MarginModeSwitchSheetId = "MarginModeSwitchSheetId";
|
|
2728
|
+
var MarginModeSwitchDialogId = "MarginModeSwitchDialogId";
|
|
2729
|
+
ui.registerSimpleSheet(MarginModeSwitchSheetId, MarginModeSwitchWidget, {
|
|
2730
|
+
// Use custom header in widget UI for both web and mweb.
|
|
2731
|
+
title: void 0,
|
|
2732
|
+
closable: false,
|
|
2733
|
+
classNames: {
|
|
2734
|
+
content: "oui-bg-transparent !oui-px-0",
|
|
2735
|
+
body: "oui-p-0"
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
ui.registerSimpleDialog(MarginModeSwitchDialogId, MarginModeSwitchWidget, {
|
|
2739
|
+
// Use custom header in widget UI for both web and mweb.
|
|
2740
|
+
title: void 0,
|
|
2741
|
+
closable: false,
|
|
2742
|
+
classNames: {
|
|
2743
|
+
content: "oui-w-[360px] oui-bg-transparent !oui-px-0",
|
|
2744
|
+
body: "oui-p-0"
|
|
2745
|
+
}
|
|
2746
|
+
});
|
|
1924
2747
|
var LeverageBadge = (props) => {
|
|
1925
|
-
const { symbol, side, symbolLeverage } = props;
|
|
2748
|
+
const { symbol, side, symbolLeverage, disabled } = props;
|
|
1926
2749
|
const { isMobile } = ui.useScreen();
|
|
1927
|
-
const {
|
|
1928
|
-
const
|
|
1929
|
-
const
|
|
2750
|
+
const { t } = i18n.useTranslation();
|
|
2751
|
+
const { enabled } = hooks.useFeatureFlag(hooks.FlagKeys.IsolatedMargin);
|
|
2752
|
+
const marginMode = props.marginMode;
|
|
2753
|
+
const isDisabled = !!disabled;
|
|
2754
|
+
const curLeverage = symbolLeverage ?? 1;
|
|
2755
|
+
const showLeverageModal = () => {
|
|
2756
|
+
if (isDisabled) return;
|
|
1930
2757
|
const modalId = isMobile ? uiLeverage.SymbolLeverageSheetId : uiLeverage.SymbolLeverageDialogId;
|
|
1931
2758
|
ui.modal.show(modalId, {
|
|
1932
2759
|
symbol,
|
|
1933
2760
|
side,
|
|
1934
|
-
curLeverage
|
|
2761
|
+
curLeverage,
|
|
2762
|
+
marginMode
|
|
2763
|
+
});
|
|
2764
|
+
};
|
|
2765
|
+
const showMarginModeModal = () => {
|
|
2766
|
+
if (isDisabled || !enabled) {
|
|
2767
|
+
return;
|
|
2768
|
+
}
|
|
2769
|
+
const modalId = isMobile ? MarginModeSwitchSheetId : MarginModeSwitchDialogId;
|
|
2770
|
+
ui.modal.show(modalId, {
|
|
2771
|
+
symbol
|
|
1935
2772
|
});
|
|
1936
2773
|
};
|
|
1937
2774
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1938
|
-
|
|
2775
|
+
"div",
|
|
1939
2776
|
{
|
|
1940
|
-
justify: "center",
|
|
1941
|
-
itemAlign: "center",
|
|
1942
|
-
gapX: 1,
|
|
1943
2777
|
className: ui.cn(
|
|
2778
|
+
"oui-flex oui-w-full oui-items-center oui-rounded-md oui-border oui-border-line-12 oui-bg-base-6",
|
|
1944
2779
|
"oui-orderEntry-leverage-btn",
|
|
1945
2780
|
"oui-h-8",
|
|
1946
|
-
"oui-
|
|
1947
|
-
"oui-cursor-pointer oui-select-none oui-text-xs oui-font-semibold oui-text-base-contrast-54"
|
|
2781
|
+
"oui-select-none"
|
|
1948
2782
|
),
|
|
1949
|
-
|
|
2783
|
+
"data-testid": "oui-testid-orderEntry-margin-leverage",
|
|
1950
2784
|
children: [
|
|
1951
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1952
|
-
|
|
2785
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2786
|
+
"button",
|
|
2787
|
+
{
|
|
2788
|
+
type: "button",
|
|
2789
|
+
className: ui.cn(
|
|
2790
|
+
"oui-flex oui-flex-1 oui-items-center oui-justify-center oui-gap-x-1",
|
|
2791
|
+
"oui-px-3 oui-py-1.5",
|
|
2792
|
+
"oui-text-xs oui-font-semibold oui-text-base-contrast-54",
|
|
2793
|
+
isDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
|
|
2794
|
+
),
|
|
2795
|
+
"data-testid": "oui-testid-orderEntry-margin-mode",
|
|
2796
|
+
"aria-label": t("marginMode.switchMarginMode"),
|
|
2797
|
+
disabled: isDisabled,
|
|
2798
|
+
onClick: showMarginModeModal,
|
|
2799
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: marginMode === void 0 ? "--" : marginMode === types.MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross") })
|
|
2800
|
+
}
|
|
2801
|
+
),
|
|
2802
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-h-5 oui-w-px oui-bg-line", "aria-hidden": "true" }),
|
|
2803
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2804
|
+
"button",
|
|
2805
|
+
{
|
|
2806
|
+
type: "button",
|
|
2807
|
+
className: ui.cn(
|
|
2808
|
+
"oui-flex oui-flex-1 oui-items-center oui-justify-center oui-gap-x-1",
|
|
2809
|
+
"oui-px-3 oui-py-1.5",
|
|
2810
|
+
"oui-text-xs oui-font-semibold oui-text-base-contrast-54",
|
|
2811
|
+
isDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
|
|
2812
|
+
),
|
|
2813
|
+
"aria-label": "Adjust leverage",
|
|
2814
|
+
disabled: isDisabled,
|
|
2815
|
+
onClick: showLeverageModal,
|
|
2816
|
+
"data-testid": "oui-testid-orderEntry-leverage",
|
|
2817
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2818
|
+
ui.Text.numeral,
|
|
2819
|
+
{
|
|
2820
|
+
dp: 0,
|
|
2821
|
+
rm: utils.Decimal.ROUND_DOWN,
|
|
2822
|
+
unit: "x",
|
|
2823
|
+
unitClassName: "oui-ml-0",
|
|
2824
|
+
children: curLeverage
|
|
2825
|
+
}
|
|
2826
|
+
)
|
|
2827
|
+
}
|
|
2828
|
+
)
|
|
1953
2829
|
]
|
|
1954
2830
|
}
|
|
1955
2831
|
);
|
|
@@ -1958,6 +2834,27 @@ function OrderEntryHeader(props) {
|
|
|
1958
2834
|
const { canTrade, side, order_type, setOrderValue } = props;
|
|
1959
2835
|
const { t } = i18n.useTranslation();
|
|
1960
2836
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2837
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2838
|
+
LeverageBadge,
|
|
2839
|
+
{
|
|
2840
|
+
symbol: props.symbol,
|
|
2841
|
+
side: props.side,
|
|
2842
|
+
symbolLeverage: props.symbolLeverage,
|
|
2843
|
+
marginMode: props.marginMode,
|
|
2844
|
+
disabled: !props.canTrade
|
|
2845
|
+
}
|
|
2846
|
+
) }),
|
|
2847
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2848
|
+
OrderTypeSelect,
|
|
2849
|
+
{
|
|
2850
|
+
type: order_type,
|
|
2851
|
+
side,
|
|
2852
|
+
canTrade,
|
|
2853
|
+
onChange: (type) => {
|
|
2854
|
+
setOrderValue("order_type", type);
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
) }),
|
|
1961
2858
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1962
2859
|
"div",
|
|
1963
2860
|
{
|
|
@@ -2003,45 +2900,14 @@ function OrderEntryHeader(props) {
|
|
|
2003
2900
|
)
|
|
2004
2901
|
]
|
|
2005
2902
|
}
|
|
2006
|
-
),
|
|
2007
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2008
|
-
"div",
|
|
2009
|
-
{
|
|
2010
|
-
className: ui.cn(
|
|
2011
|
-
"oui-orderEntry-header-controls",
|
|
2012
|
-
"oui-grid oui-gap-x-2 lg:oui-flex lg:oui-gap-x-[6px]",
|
|
2013
|
-
"oui-grid-cols-2"
|
|
2014
|
-
),
|
|
2015
|
-
children: [
|
|
2016
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full oui-orderEntry-orderTypeSelect", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2017
|
-
OrderTypeSelect,
|
|
2018
|
-
{
|
|
2019
|
-
type: order_type,
|
|
2020
|
-
side,
|
|
2021
|
-
canTrade,
|
|
2022
|
-
onChange: (type) => {
|
|
2023
|
-
setOrderValue("order_type", type);
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
) }),
|
|
2027
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full oui-orderEntry-leverage", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2028
|
-
LeverageBadge,
|
|
2029
|
-
{
|
|
2030
|
-
symbol: props.symbol,
|
|
2031
|
-
side: props.side,
|
|
2032
|
-
symbolLeverage: props.symbolLeverage
|
|
2033
|
-
}
|
|
2034
|
-
) })
|
|
2035
|
-
]
|
|
2036
|
-
}
|
|
2037
2903
|
)
|
|
2038
2904
|
] });
|
|
2039
2905
|
}
|
|
2040
|
-
var OrderEntryContext =
|
|
2906
|
+
var OrderEntryContext = React3.createContext(
|
|
2041
2907
|
{}
|
|
2042
2908
|
);
|
|
2043
2909
|
var useOrderEntryContext = () => {
|
|
2044
|
-
return
|
|
2910
|
+
return React3.useContext(OrderEntryContext);
|
|
2045
2911
|
};
|
|
2046
2912
|
var OrderEntryProvider = (props) => {
|
|
2047
2913
|
const {
|
|
@@ -2061,7 +2927,7 @@ var OrderEntryProvider = (props) => {
|
|
|
2061
2927
|
lastQuantityInputType,
|
|
2062
2928
|
leverage
|
|
2063
2929
|
} = props;
|
|
2064
|
-
const memoizedValue =
|
|
2930
|
+
const memoizedValue = React3.useMemo(() => {
|
|
2065
2931
|
return {
|
|
2066
2932
|
errorMsgVisible,
|
|
2067
2933
|
symbolInfo,
|
|
@@ -2099,7 +2965,7 @@ var OrderEntryProvider = (props) => {
|
|
|
2099
2965
|
]);
|
|
2100
2966
|
return /* @__PURE__ */ jsxRuntime.jsx(OrderEntryContext.Provider, { value: memoizedValue, children: props.children });
|
|
2101
2967
|
};
|
|
2102
|
-
var CustomInput =
|
|
2968
|
+
var CustomInput = React3.forwardRef(
|
|
2103
2969
|
(props, ref) => {
|
|
2104
2970
|
const { placeholder = "0" } = props;
|
|
2105
2971
|
const { errorMsgVisible } = useOrderEntryContext();
|
|
@@ -2166,7 +3032,7 @@ var InputLabel = (props) => {
|
|
|
2166
3032
|
};
|
|
2167
3033
|
var BBOOrderTypeSelect = (props) => {
|
|
2168
3034
|
const { t } = i18n.useTranslation();
|
|
2169
|
-
const options2 =
|
|
3035
|
+
const options2 = React3.useMemo(
|
|
2170
3036
|
() => [
|
|
2171
3037
|
{
|
|
2172
3038
|
label: t("orderEntry.bbo.counterparty1"),
|
|
@@ -2359,7 +3225,7 @@ var PriceInput = (props) => {
|
|
|
2359
3225
|
}
|
|
2360
3226
|
);
|
|
2361
3227
|
};
|
|
2362
|
-
var QuantityInput =
|
|
3228
|
+
var QuantityInput = React3.memo((props) => {
|
|
2363
3229
|
const { t } = i18n.useTranslation();
|
|
2364
3230
|
const { symbolInfo, onFocus, onBlur, getErrorMsg, setOrderValue } = useOrderEntryContext();
|
|
2365
3231
|
const { base, base_dp } = symbolInfo;
|
|
@@ -2386,9 +3252,9 @@ var QuantityInput = React2.memo((props) => {
|
|
|
2386
3252
|
);
|
|
2387
3253
|
});
|
|
2388
3254
|
QuantityInput.displayName = "QuantityInput";
|
|
2389
|
-
var TotalTypeSelect =
|
|
3255
|
+
var TotalTypeSelect = React3.memo((props) => {
|
|
2390
3256
|
const { t } = i18n.useTranslation();
|
|
2391
|
-
const options2 =
|
|
3257
|
+
const options2 = React3.useMemo(() => {
|
|
2392
3258
|
return [
|
|
2393
3259
|
{
|
|
2394
3260
|
label: t("orderEntry.orderSize"),
|
|
@@ -2422,10 +3288,10 @@ var TotalTypeSelect = React2.memo((props) => {
|
|
|
2422
3288
|
);
|
|
2423
3289
|
});
|
|
2424
3290
|
TotalTypeSelect.displayName = "TotalTypeSelect";
|
|
2425
|
-
var TotalInput =
|
|
3291
|
+
var TotalInput = React3.memo((props) => {
|
|
2426
3292
|
const { t } = i18n.useTranslation();
|
|
2427
3293
|
const { total } = props;
|
|
2428
|
-
const [margin, setMargin] =
|
|
3294
|
+
const [margin, setMargin] = React3.useState("");
|
|
2429
3295
|
const {
|
|
2430
3296
|
symbolInfo,
|
|
2431
3297
|
onFocus,
|
|
@@ -2440,7 +3306,7 @@ var TotalInput = React2.memo((props) => {
|
|
|
2440
3306
|
"orderly_order_total_type",
|
|
2441
3307
|
"orderSize" /* OrderSize */
|
|
2442
3308
|
);
|
|
2443
|
-
|
|
3309
|
+
React3.useEffect(() => {
|
|
2444
3310
|
if (total) {
|
|
2445
3311
|
if (currentFocusInput !== 6 /* MARGIN */) {
|
|
2446
3312
|
const margin2 = new utils.Decimal(total).div(leverage).todp(2).toString();
|
|
@@ -2502,7 +3368,7 @@ var TotalInput = React2.memo((props) => {
|
|
|
2502
3368
|
);
|
|
2503
3369
|
});
|
|
2504
3370
|
TotalInput.displayName = "TotalInput";
|
|
2505
|
-
var QtyAndTotalInput =
|
|
3371
|
+
var QtyAndTotalInput = React3.memo((props) => {
|
|
2506
3372
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2507
3373
|
ui.Grid,
|
|
2508
3374
|
{
|
|
@@ -2516,7 +3382,7 @@ var QtyAndTotalInput = React2.memo((props) => {
|
|
|
2516
3382
|
);
|
|
2517
3383
|
});
|
|
2518
3384
|
QtyAndTotalInput.displayName = "QtyAndTotalInput";
|
|
2519
|
-
var QuantityDistributionInput =
|
|
3385
|
+
var QuantityDistributionInput = React3.memo((props) => {
|
|
2520
3386
|
const { t } = i18n.useTranslation();
|
|
2521
3387
|
const { setOrderValue } = useOrderEntryContext();
|
|
2522
3388
|
const showHint = () => {
|
|
@@ -2570,8 +3436,8 @@ var QuantityDistributionInput = React2.memo((props) => {
|
|
|
2570
3436
|
});
|
|
2571
3437
|
var QuantityDistributionHint = (props) => {
|
|
2572
3438
|
const { t } = i18n.useTranslation();
|
|
2573
|
-
const [type, setType] =
|
|
2574
|
-
|
|
3439
|
+
const [type, setType] = React3.useState(types.DistributionType.FLAT);
|
|
3440
|
+
React3.useEffect(() => {
|
|
2575
3441
|
setType(
|
|
2576
3442
|
[
|
|
2577
3443
|
types.DistributionType.FLAT,
|
|
@@ -2580,7 +3446,7 @@ var QuantityDistributionHint = (props) => {
|
|
|
2580
3446
|
].includes(props.value) ? props.value : types.DistributionType.FLAT
|
|
2581
3447
|
);
|
|
2582
3448
|
}, [props.value]);
|
|
2583
|
-
const content =
|
|
3449
|
+
const content = React3.useMemo(() => {
|
|
2584
3450
|
return [
|
|
2585
3451
|
{
|
|
2586
3452
|
type: types.DistributionType.FLAT,
|
|
@@ -2605,7 +3471,7 @@ var QuantityDistributionHint = (props) => {
|
|
|
2605
3471
|
}
|
|
2606
3472
|
];
|
|
2607
3473
|
}, []);
|
|
2608
|
-
const currentContent =
|
|
3474
|
+
const currentContent = React3.useMemo(() => {
|
|
2609
3475
|
return content.find((item) => item.type === type);
|
|
2610
3476
|
}, [content, type]);
|
|
2611
3477
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-text-2xs oui-font-semibold oui-text-base-contrast-54", children: [
|
|
@@ -2663,7 +3529,7 @@ var QuantityDistribution = (props) => {
|
|
|
2663
3529
|
const onChange = (value2) => (checked) => {
|
|
2664
3530
|
onValueChange(value2);
|
|
2665
3531
|
};
|
|
2666
|
-
const distributionTypeMap =
|
|
3532
|
+
const distributionTypeMap = React3.useMemo(() => {
|
|
2667
3533
|
return {
|
|
2668
3534
|
[types.DistributionType.FLAT]: t("orderEntry.distributionType.flat"),
|
|
2669
3535
|
[types.DistributionType.ASCENDING]: t(
|
|
@@ -2974,7 +3840,7 @@ var PriceChart = () => {
|
|
|
2974
3840
|
}
|
|
2975
3841
|
);
|
|
2976
3842
|
};
|
|
2977
|
-
var ScaledPriceInput =
|
|
3843
|
+
var ScaledPriceInput = React3.memo((props) => {
|
|
2978
3844
|
const { t } = i18n.useTranslation();
|
|
2979
3845
|
const { symbolInfo, onFocus, onBlur, getErrorMsg, setOrderValue } = useOrderEntryContext();
|
|
2980
3846
|
const { quote, quote_dp } = symbolInfo;
|
|
@@ -3024,7 +3890,7 @@ var valueRenderer = (value) => {
|
|
|
3024
3890
|
};
|
|
3025
3891
|
var ScaledQuantityUnit = (props) => {
|
|
3026
3892
|
const { base, quote } = props;
|
|
3027
|
-
const options2 =
|
|
3893
|
+
const options2 = React3.useMemo(() => {
|
|
3028
3894
|
return [{ name: quote }, { name: base }];
|
|
3029
3895
|
}, [base, quote]);
|
|
3030
3896
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3054,7 +3920,7 @@ var ScaledQuantityUnit = (props) => {
|
|
|
3054
3920
|
}
|
|
3055
3921
|
);
|
|
3056
3922
|
};
|
|
3057
|
-
var ScaledQuantityInput =
|
|
3923
|
+
var ScaledQuantityInput = React3.memo((props) => {
|
|
3058
3924
|
const { t } = i18n.useTranslation();
|
|
3059
3925
|
const { errors, symbolInfo, onFocus, onBlur, getErrorMsg, setOrderValue } = useOrderEntryContext();
|
|
3060
3926
|
const [quantityUnit, setQuantityUnit] = hooks.useLocalStorage(
|
|
@@ -3117,7 +3983,7 @@ var ScaledQuantityInput = React2.memo((props) => {
|
|
|
3117
3983
|
}
|
|
3118
3984
|
);
|
|
3119
3985
|
});
|
|
3120
|
-
var SkewInput =
|
|
3986
|
+
var SkewInput = React3.memo((props) => {
|
|
3121
3987
|
const { t } = i18n.useTranslation();
|
|
3122
3988
|
const { onFocus, onBlur, getErrorMsg, setOrderValue } = useOrderEntryContext();
|
|
3123
3989
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3143,7 +4009,7 @@ var SkewInput = React2.memo((props) => {
|
|
|
3143
4009
|
}
|
|
3144
4010
|
);
|
|
3145
4011
|
});
|
|
3146
|
-
var TotalOrdersInput =
|
|
4012
|
+
var TotalOrdersInput = React3.memo((props) => {
|
|
3147
4013
|
const { t } = i18n.useTranslation();
|
|
3148
4014
|
const { onFocus, onBlur, getErrorMsg, setOrderValue } = useOrderEntryContext();
|
|
3149
4015
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3206,7 +4072,7 @@ var ScaledOrderInput = (props) => {
|
|
|
3206
4072
|
showSkewInput && /* @__PURE__ */ jsxRuntime.jsx(SkewInput, { skew: values.skew })
|
|
3207
4073
|
] });
|
|
3208
4074
|
};
|
|
3209
|
-
var TriggerPriceInput =
|
|
4075
|
+
var TriggerPriceInput = React3.memo((props) => {
|
|
3210
4076
|
const { t } = i18n.useTranslation();
|
|
3211
4077
|
const {
|
|
3212
4078
|
symbolInfo,
|
|
@@ -3237,7 +4103,7 @@ var TriggerPriceInput = React2.memo((props) => {
|
|
|
3237
4103
|
) });
|
|
3238
4104
|
});
|
|
3239
4105
|
TriggerPriceInput.displayName = "TriggerPriceInput";
|
|
3240
|
-
var ActivePriceInput =
|
|
4106
|
+
var ActivePriceInput = React3.memo((props) => {
|
|
3241
4107
|
const { t } = i18n.useTranslation();
|
|
3242
4108
|
const {
|
|
3243
4109
|
symbolInfo,
|
|
@@ -3270,7 +4136,7 @@ var ActivePriceInput = React2.memo((props) => {
|
|
|
3270
4136
|
});
|
|
3271
4137
|
ActivePriceInput.displayName = "ActivePriceInput";
|
|
3272
4138
|
var percentages = [1, 2, 3, 5];
|
|
3273
|
-
var CallbackRatePercentages =
|
|
4139
|
+
var CallbackRatePercentages = React3.memo(
|
|
3274
4140
|
(props) => {
|
|
3275
4141
|
const { setOrderValue } = useOrderEntryContext();
|
|
3276
4142
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gapX: 2, className: props.className, children: percentages.map((item) => {
|
|
@@ -3303,10 +4169,10 @@ var CallbackRatePercentages = React2.memo(
|
|
|
3303
4169
|
}
|
|
3304
4170
|
);
|
|
3305
4171
|
CallbackRatePercentages.displayName = "CallbackRatePercentages";
|
|
3306
|
-
var TrailingCallbackSelect =
|
|
4172
|
+
var TrailingCallbackSelect = React3.memo(
|
|
3307
4173
|
(props) => {
|
|
3308
4174
|
const { quote } = props;
|
|
3309
|
-
const options2 =
|
|
4175
|
+
const options2 = React3.useMemo(() => {
|
|
3310
4176
|
return [
|
|
3311
4177
|
{ label: quote, value: types.TrailingCallbackType.VALUE },
|
|
3312
4178
|
{ label: "%", value: types.TrailingCallbackType.RATE }
|
|
@@ -3339,7 +4205,7 @@ var TrailingCallbackSelect = React2.memo(
|
|
|
3339
4205
|
}
|
|
3340
4206
|
);
|
|
3341
4207
|
TrailingCallbackSelect.displayName = "trailingCallbackSelect";
|
|
3342
|
-
var TrailingCallbackInput =
|
|
4208
|
+
var TrailingCallbackInput = React3.memo(
|
|
3343
4209
|
(props) => {
|
|
3344
4210
|
const { callback_value, callback_rate } = props;
|
|
3345
4211
|
const { t } = i18n.useTranslation();
|
|
@@ -3352,13 +4218,13 @@ var TrailingCallbackInput = React2.memo(
|
|
|
3352
4218
|
setOrderValues
|
|
3353
4219
|
} = useOrderEntryContext();
|
|
3354
4220
|
const { quote, quote_dp } = symbolInfo;
|
|
3355
|
-
const lastCallbackValueRef =
|
|
3356
|
-
const lastCallbackRateRef =
|
|
4221
|
+
const lastCallbackValueRef = React3.useRef();
|
|
4222
|
+
const lastCallbackRateRef = React3.useRef();
|
|
3357
4223
|
const [callbackType, setCallbackType] = hooks.useLocalStorage(
|
|
3358
4224
|
"orderly_order_trailing_callback_type",
|
|
3359
4225
|
types.TrailingCallbackType.VALUE
|
|
3360
4226
|
);
|
|
3361
|
-
const onCallbackTypeChange =
|
|
4227
|
+
const onCallbackTypeChange = React3.useCallback(
|
|
3362
4228
|
(type) => {
|
|
3363
4229
|
setCallbackType(type);
|
|
3364
4230
|
if (type === types.TrailingCallbackType.RATE) {
|
|
@@ -3512,17 +4378,17 @@ function OrderInput(props) {
|
|
|
3512
4378
|
}
|
|
3513
4379
|
var SLIDER_MIN = 0;
|
|
3514
4380
|
var SLIDER_MAX = 100;
|
|
3515
|
-
var QuantitySlider =
|
|
4381
|
+
var QuantitySlider = React3.memo((props) => {
|
|
3516
4382
|
const { canTrade, side, order_quantity, maxQty } = props;
|
|
3517
|
-
const [sliderValue, setSliderValue] =
|
|
4383
|
+
const [sliderValue, setSliderValue] = React3.useState(0);
|
|
3518
4384
|
const { setOrderValue, symbolInfo, lastQuantityInputType } = useOrderEntryContext();
|
|
3519
4385
|
const { base_dp, base_tick } = symbolInfo;
|
|
3520
4386
|
const { t } = i18n.useTranslation();
|
|
3521
|
-
const color =
|
|
4387
|
+
const color = React3.useMemo(
|
|
3522
4388
|
() => canTrade ? side === types.OrderSide.BUY ? "buy" : "sell" : void 0,
|
|
3523
4389
|
[side, canTrade]
|
|
3524
4390
|
);
|
|
3525
|
-
const maxLabel =
|
|
4391
|
+
const maxLabel = React3.useMemo(() => {
|
|
3526
4392
|
return side === types.OrderSide.BUY ? t("orderEntry.maxBuy") : t("orderEntry.maxSell");
|
|
3527
4393
|
}, [side, t]);
|
|
3528
4394
|
const onSliderValueChange = (value) => {
|
|
@@ -3539,12 +4405,12 @@ var QuantitySlider = React2.memo((props) => {
|
|
|
3539
4405
|
sliderToQuantity(SLIDER_MAX);
|
|
3540
4406
|
}
|
|
3541
4407
|
};
|
|
3542
|
-
|
|
4408
|
+
React3.useEffect(() => {
|
|
3543
4409
|
if (lastQuantityInputType.current === 4 /* QUANTITY_SLIDER */) {
|
|
3544
4410
|
sliderToQuantity(sliderValue);
|
|
3545
4411
|
}
|
|
3546
4412
|
}, [sliderValue, maxQty]);
|
|
3547
|
-
|
|
4413
|
+
React3.useEffect(() => {
|
|
3548
4414
|
const quantityToSlider = () => {
|
|
3549
4415
|
if (order_quantity && Number(order_quantity) !== 0 && maxQty !== 0) {
|
|
3550
4416
|
return new utils.Decimal(Math.min(Number(order_quantity), maxQty)).div(maxQty).mul(SLIDER_MAX).todp(2, utils.Decimal.ROUND_DOWN).toNumber();
|
|
@@ -3655,22 +4521,22 @@ var ReduceOnlySwitch = ({
|
|
|
3655
4521
|
}
|
|
3656
4522
|
);
|
|
3657
4523
|
};
|
|
3658
|
-
var PnlInputContext =
|
|
4524
|
+
var PnlInputContext = React3.createContext(
|
|
3659
4525
|
{}
|
|
3660
4526
|
);
|
|
3661
4527
|
var usePnlInputContext = () => {
|
|
3662
|
-
return
|
|
4528
|
+
return React3.useContext(PnlInputContext);
|
|
3663
4529
|
};
|
|
3664
4530
|
|
|
3665
4531
|
// src/components/pnlInput/useBuilder.script.ts
|
|
3666
4532
|
var usePNLInputBuilder = (props) => {
|
|
3667
4533
|
const { type, values, quote_dp } = props;
|
|
3668
4534
|
const { t } = i18n.useTranslation();
|
|
3669
|
-
const [focus, setFocus] =
|
|
4535
|
+
const [focus, setFocus] = React3.useState(true);
|
|
3670
4536
|
const { mode, setMode, tipsEle } = usePnlInputContext();
|
|
3671
|
-
const [tipVisible, setTipVisible] =
|
|
3672
|
-
const [isFocused, setIsFocused] =
|
|
3673
|
-
const key =
|
|
4537
|
+
const [tipVisible, setTipVisible] = React3.useState(false);
|
|
4538
|
+
const [isFocused, setIsFocused] = React3.useState(false);
|
|
4539
|
+
const key = React3.useMemo(() => {
|
|
3674
4540
|
switch (mode) {
|
|
3675
4541
|
case "Offset" /* OFFSET */:
|
|
3676
4542
|
return `${type.toLowerCase()}_offset`;
|
|
@@ -3680,16 +4546,16 @@ var usePNLInputBuilder = (props) => {
|
|
|
3680
4546
|
return `${type.toLowerCase()}_pnl`;
|
|
3681
4547
|
}
|
|
3682
4548
|
}, [mode]);
|
|
3683
|
-
const [innerValue, setInnerValue] =
|
|
4549
|
+
const [innerValue, setInnerValue] = React3.useState(
|
|
3684
4550
|
values[mode]
|
|
3685
4551
|
);
|
|
3686
|
-
|
|
4552
|
+
React3.useEffect(() => {
|
|
3687
4553
|
if (isFocused) {
|
|
3688
4554
|
return;
|
|
3689
4555
|
}
|
|
3690
4556
|
setInnerValue(values[mode]);
|
|
3691
4557
|
}, [values, mode, isFocused]);
|
|
3692
|
-
const modes =
|
|
4558
|
+
const modes = React3.useMemo(() => {
|
|
3693
4559
|
return [
|
|
3694
4560
|
{
|
|
3695
4561
|
label: t("tpsl.pnl"),
|
|
@@ -3708,14 +4574,14 @@ var usePNLInputBuilder = (props) => {
|
|
|
3708
4574
|
}
|
|
3709
4575
|
];
|
|
3710
4576
|
}, [t]);
|
|
3711
|
-
const modeLabelMap =
|
|
4577
|
+
const modeLabelMap = React3.useMemo(() => {
|
|
3712
4578
|
return {
|
|
3713
4579
|
["PnL" /* PnL */]: t("tpsl.pnl"),
|
|
3714
4580
|
["Offset" /* OFFSET */]: t("tpsl.offset"),
|
|
3715
4581
|
["Offset%" /* PERCENTAGE */]: `${t("tpsl.offset")}%`
|
|
3716
4582
|
};
|
|
3717
4583
|
}, [t]);
|
|
3718
|
-
const percentageSuffix =
|
|
4584
|
+
const percentageSuffix = React3.useRef("");
|
|
3719
4585
|
const onValueChange = (value) => {
|
|
3720
4586
|
setInnerValue(value);
|
|
3721
4587
|
props.onChange(key, value);
|
|
@@ -3811,18 +4677,18 @@ var PNLInput = (props) => {
|
|
|
3811
4677
|
onBlur,
|
|
3812
4678
|
setFocus
|
|
3813
4679
|
} = props;
|
|
3814
|
-
const [prefix, setPrefix] =
|
|
3815
|
-
const [placeholder, setPlaceholder] =
|
|
4680
|
+
const [prefix, setPrefix] = React3.useState(mode);
|
|
4681
|
+
const [placeholder, setPlaceholder] = React3.useState(
|
|
3816
4682
|
mode === "Offset%" /* PERCENTAGE */ ? "%" : quote
|
|
3817
4683
|
);
|
|
3818
|
-
|
|
4684
|
+
React3.useEffect(() => {
|
|
3819
4685
|
setPrefix(mode);
|
|
3820
4686
|
setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
|
|
3821
4687
|
}, [mode]);
|
|
3822
|
-
|
|
4688
|
+
React3.useEffect(() => {
|
|
3823
4689
|
setPrefix(!!value ? "" : mode);
|
|
3824
4690
|
}, [value]);
|
|
3825
|
-
const id =
|
|
4691
|
+
const id = React3.useMemo(() => `${type.toLowerCase()}_${mode.toLowerCase()}`, []);
|
|
3826
4692
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3827
4693
|
ui.Input.tooltip,
|
|
3828
4694
|
{
|
|
@@ -3915,7 +4781,7 @@ var PnlInputProvider = (props) => {
|
|
|
3915
4781
|
"Offset%" /* PERCENTAGE */
|
|
3916
4782
|
);
|
|
3917
4783
|
const { t } = i18n.useTranslation();
|
|
3918
|
-
const tipsEle =
|
|
4784
|
+
const tipsEle = React3.useMemo(() => {
|
|
3919
4785
|
if (!values.PnL || !values.trigger_price) {
|
|
3920
4786
|
return null;
|
|
3921
4787
|
}
|
|
@@ -3944,16 +4810,16 @@ var PnlInputProvider = (props) => {
|
|
|
3944
4810
|
)
|
|
3945
4811
|
] });
|
|
3946
4812
|
}, [mode, values.ROI, values.PnL, values.trigger_price]);
|
|
3947
|
-
const memoizedValue =
|
|
4813
|
+
const memoizedValue = React3.useMemo(() => {
|
|
3948
4814
|
return { mode, setMode, tipsEle };
|
|
3949
4815
|
}, [mode, setMode, tipsEle]);
|
|
3950
4816
|
return /* @__PURE__ */ jsxRuntime.jsx(PnlInputContext.Provider, { value: memoizedValue, children });
|
|
3951
4817
|
};
|
|
3952
4818
|
var OrderTPSL = (props) => {
|
|
3953
|
-
const tpslFormRef =
|
|
4819
|
+
const tpslFormRef = React3__default.default.useRef(null);
|
|
3954
4820
|
const { t } = i18n.useTranslation();
|
|
3955
4821
|
const { isMobile } = ui.useScreen();
|
|
3956
|
-
|
|
4822
|
+
React3.useEffect(() => {
|
|
3957
4823
|
if (props.orderType !== types.OrderType.LIMIT && props.orderType !== types.OrderType.MARKET) {
|
|
3958
4824
|
props.onSwitchChanged(false);
|
|
3959
4825
|
}
|
|
@@ -4051,7 +4917,7 @@ var TPSLPriceWarning = (props) => {
|
|
|
4051
4917
|
}
|
|
4052
4918
|
);
|
|
4053
4919
|
};
|
|
4054
|
-
var TPSLInputForm =
|
|
4920
|
+
var TPSLInputForm = React3__default.default.forwardRef((props, ref) => {
|
|
4055
4921
|
const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(props.errors);
|
|
4056
4922
|
const { t } = i18n.useTranslation();
|
|
4057
4923
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4156,20 +5022,20 @@ var TPSLTriggerPriceInput = (props) => {
|
|
|
4156
5022
|
const { t } = i18n.useTranslation();
|
|
4157
5023
|
const { errorMsgVisible } = useOrderEntryContext();
|
|
4158
5024
|
const { tipsEle } = usePnlInputContext();
|
|
4159
|
-
const [prefix, setPrefix] =
|
|
4160
|
-
const [placeholder, setPlaceholder] =
|
|
4161
|
-
const [tipVisible, setTipVisible] =
|
|
4162
|
-
const [isFocused, setIsFocused] =
|
|
4163
|
-
const [innerValue, setInnerValue] =
|
|
5025
|
+
const [prefix, setPrefix] = React3.useState(`${props.type} Price`);
|
|
5026
|
+
const [placeholder, setPlaceholder] = React3.useState("USDC");
|
|
5027
|
+
const [tipVisible, setTipVisible] = React3.useState(false);
|
|
5028
|
+
const [isFocused, setIsFocused] = React3.useState(false);
|
|
5029
|
+
const [innerValue, setInnerValue] = React3.useState(
|
|
4164
5030
|
props.values.trigger_price ?? ""
|
|
4165
5031
|
);
|
|
4166
|
-
|
|
5032
|
+
React3.useEffect(() => {
|
|
4167
5033
|
if (isFocused) {
|
|
4168
5034
|
return;
|
|
4169
5035
|
}
|
|
4170
5036
|
setInnerValue(props.values.trigger_price ?? "");
|
|
4171
5037
|
}, [props.values.trigger_price, isFocused]);
|
|
4172
|
-
const triggerPriceToolTipEle =
|
|
5038
|
+
const triggerPriceToolTipEle = React3.useMemo(() => {
|
|
4173
5039
|
if (props.error && (errorMsgVisible || props.displayErrorMessage))
|
|
4174
5040
|
return props.error;
|
|
4175
5041
|
if (tipVisible) return tipsEle;
|
|
@@ -4192,7 +5058,7 @@ var TPSLTriggerPriceInput = (props) => {
|
|
|
4192
5058
|
setInnerValue(value);
|
|
4193
5059
|
props.onChange(value);
|
|
4194
5060
|
};
|
|
4195
|
-
|
|
5061
|
+
React3.useEffect(() => {
|
|
4196
5062
|
setPrefix(getPrefixLabel(props.values.trigger_price));
|
|
4197
5063
|
if (!isFocused) {
|
|
4198
5064
|
setInnerValue(props.values.trigger_price ?? "");
|
|
@@ -4316,12 +5182,12 @@ var OrderEntry = (props) => {
|
|
|
4316
5182
|
setSoundAlert,
|
|
4317
5183
|
currentFocusInput
|
|
4318
5184
|
} = props;
|
|
4319
|
-
const [maxQtyConfirmOpen, setMaxQtyConfirmOpen] =
|
|
5185
|
+
const [maxQtyConfirmOpen, setMaxQtyConfirmOpen] = React3.useState(false);
|
|
4320
5186
|
const { t } = i18n.useTranslation();
|
|
4321
5187
|
const { isMobile } = ui.useScreen();
|
|
4322
|
-
const [hasAdvancedTPSLResult, setHasAdvancedTPSLResult] =
|
|
5188
|
+
const [hasAdvancedTPSLResult, setHasAdvancedTPSLResult] = React3.useState(false);
|
|
4323
5189
|
const { errors, validated } = metaState;
|
|
4324
|
-
const [errorMsgVisible, setErrorMsgVisible] =
|
|
5190
|
+
const [errorMsgVisible, setErrorMsgVisible] = React3.useState(false);
|
|
4325
5191
|
const [needConfirm, setNeedConfirm] = hooks.useLocalStorage(
|
|
4326
5192
|
"orderly_order_confirm",
|
|
4327
5193
|
true
|
|
@@ -4330,7 +5196,7 @@ var OrderEntry = (props) => {
|
|
|
4330
5196
|
"orderly-order-additional-pinned",
|
|
4331
5197
|
true
|
|
4332
5198
|
);
|
|
4333
|
-
const [showTPSLAdvanced, setShowTPSLAdvanced] =
|
|
5199
|
+
const [showTPSLAdvanced, setShowTPSLAdvanced] = React3.useState(false);
|
|
4334
5200
|
const [hidden, setHidden] = hooks.useLocalStorage("orderly-order-hidden", false);
|
|
4335
5201
|
const [slippage, setSlippage] = hooks.useLocalStorage("orderly-slippage", "1", {
|
|
4336
5202
|
parseJSON: ((value) => {
|
|
@@ -4338,17 +5204,17 @@ var OrderEntry = (props) => {
|
|
|
4338
5204
|
})
|
|
4339
5205
|
});
|
|
4340
5206
|
const { notification } = hooks.useOrderlyContext();
|
|
4341
|
-
const soundAlertId =
|
|
5207
|
+
const soundAlertId = React3.useId();
|
|
4342
5208
|
const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(validated ? errors : null);
|
|
4343
|
-
const buttonLabel =
|
|
5209
|
+
const buttonLabel = React3.useMemo(() => {
|
|
4344
5210
|
return side === types.OrderSide.BUY ? t("orderEntry.buyLong") : t("orderEntry.sellShort");
|
|
4345
5211
|
}, [side, t, isMobile]);
|
|
4346
|
-
|
|
5212
|
+
React3.useEffect(() => {
|
|
4347
5213
|
if (validated) {
|
|
4348
5214
|
setErrorMsgVisible(true);
|
|
4349
5215
|
}
|
|
4350
5216
|
}, [validated]);
|
|
4351
|
-
|
|
5217
|
+
React3.useEffect(() => {
|
|
4352
5218
|
if (disableFeatures?.includes("slippageSetting")) {
|
|
4353
5219
|
return;
|
|
4354
5220
|
}
|
|
@@ -4358,7 +5224,7 @@ var OrderEntry = (props) => {
|
|
|
4358
5224
|
setOrderValue("slippage", void 0);
|
|
4359
5225
|
}
|
|
4360
5226
|
}, [slippage, disableFeatures]);
|
|
4361
|
-
|
|
5227
|
+
React3.useEffect(() => {
|
|
4362
5228
|
const clickHandler = (event) => {
|
|
4363
5229
|
const target = event.target;
|
|
4364
5230
|
if (target.closest("#order-entry-submit-button")) {
|
|
@@ -4427,10 +5293,10 @@ var OrderEntry = (props) => {
|
|
|
4427
5293
|
}
|
|
4428
5294
|
});
|
|
4429
5295
|
});
|
|
4430
|
-
const formattedMaxQty =
|
|
5296
|
+
const formattedMaxQty = React3.useMemo(() => {
|
|
4431
5297
|
return new utils.Decimal(maxQty).todp(symbolInfo.base_dp, utils.Decimal.ROUND_DOWN).toString();
|
|
4432
5298
|
}, [maxQty, symbolInfo.base_dp]);
|
|
4433
|
-
const onMaxQtyConfirm =
|
|
5299
|
+
const onMaxQtyConfirm = React3.useCallback(() => {
|
|
4434
5300
|
setOrderValue("order_quantity", formattedMaxQty);
|
|
4435
5301
|
requestAnimationFrame(() => {
|
|
4436
5302
|
onSubmit();
|
|
@@ -4512,7 +5378,7 @@ var OrderEntry = (props) => {
|
|
|
4512
5378
|
position_type: types.PositionType.FULL
|
|
4513
5379
|
});
|
|
4514
5380
|
};
|
|
4515
|
-
|
|
5381
|
+
React3.useEffect(() => {
|
|
4516
5382
|
setHasAdvancedTPSLResult(false);
|
|
4517
5383
|
}, [props.symbol]);
|
|
4518
5384
|
const showReduceOnlySection = isMobile && formattedOrder.order_type !== types.OrderType.LIMIT && formattedOrder.order_type !== types.OrderType.MARKET || !isMobile;
|
|
@@ -4575,7 +5441,8 @@ var OrderEntry = (props) => {
|
|
|
4575
5441
|
side,
|
|
4576
5442
|
order_type: formattedOrder.order_type,
|
|
4577
5443
|
setOrderValue,
|
|
4578
|
-
symbolLeverage: props.symbolLeverage
|
|
5444
|
+
symbolLeverage: props.symbolLeverage,
|
|
5445
|
+
marginMode: props.marginMode
|
|
4579
5446
|
}
|
|
4580
5447
|
),
|
|
4581
5448
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4584,7 +5451,8 @@ var OrderEntry = (props) => {
|
|
|
4584
5451
|
currentLtv,
|
|
4585
5452
|
canTrade: props.canTrade,
|
|
4586
5453
|
quote: symbolInfo?.quote,
|
|
4587
|
-
freeCollateral
|
|
5454
|
+
freeCollateral,
|
|
5455
|
+
marginMode: props.marginMode
|
|
4588
5456
|
}
|
|
4589
5457
|
),
|
|
4590
5458
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4793,7 +5661,7 @@ var OrderEntry = (props) => {
|
|
|
4793
5661
|
)
|
|
4794
5662
|
},
|
|
4795
5663
|
contentProps: { side: "right", closeable: false },
|
|
4796
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5664
|
+
children: showTPSLAdvanced && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4797
5665
|
uiTpsl.TPSLAdvancedWidget,
|
|
4798
5666
|
{
|
|
4799
5667
|
setOrderValue,
|
|
@@ -4819,9 +5687,9 @@ function useBBOState({
|
|
|
4819
5687
|
setOrderValues
|
|
4820
5688
|
}) {
|
|
4821
5689
|
const [localBBOType, setLocalBBOType] = hooks.useLocalStorage("orderly_order_bbo_type", void 0);
|
|
4822
|
-
const lastBBOType =
|
|
5690
|
+
const lastBBOType = React3.useRef(localBBOType);
|
|
4823
5691
|
const { track } = hooks.useTrack();
|
|
4824
|
-
const bboStatus =
|
|
5692
|
+
const bboStatus = React3.useMemo(() => {
|
|
4825
5693
|
if (tpslSwitch || [types.OrderType.POST_ONLY, types.OrderType.IOC, types.OrderType.FOK].includes(
|
|
4826
5694
|
order_type_ext
|
|
4827
5695
|
)) {
|
|
@@ -4845,7 +5713,7 @@ function useBBOState({
|
|
|
4845
5713
|
setLocalBBOType(value);
|
|
4846
5714
|
lastBBOType.current = value;
|
|
4847
5715
|
};
|
|
4848
|
-
|
|
5716
|
+
React3.useEffect(() => {
|
|
4849
5717
|
if (bboStatus === "disabled" /* DISABLED */) {
|
|
4850
5718
|
setOrderValues({
|
|
4851
5719
|
// if order_type_ext is not bbo(ask, bid), keep previous value
|
|
@@ -4854,7 +5722,7 @@ function useBBOState({
|
|
|
4854
5722
|
});
|
|
4855
5723
|
}
|
|
4856
5724
|
}, [bboStatus, order_type_ext]);
|
|
4857
|
-
|
|
5725
|
+
React3.useEffect(() => {
|
|
4858
5726
|
if (bboStatus === "on" /* ON */) {
|
|
4859
5727
|
const orderType = getOrderTypeByBBO(localBBOType, side);
|
|
4860
5728
|
const orderLevel = getOrderLevelByBBO(localBBOType);
|
|
@@ -4874,9 +5742,9 @@ function useBBOState({
|
|
|
4874
5742
|
}
|
|
4875
5743
|
function useFocusAndBlur(props) {
|
|
4876
5744
|
const { base_tick, order_type, order_quantity, setValue } = props;
|
|
4877
|
-
const currentFocusInput =
|
|
4878
|
-
const lastScaledOrderPriceInput =
|
|
4879
|
-
const lastQuantityInputType =
|
|
5745
|
+
const currentFocusInput = React3.useRef(0 /* NONE */);
|
|
5746
|
+
const lastScaledOrderPriceInput = React3.useRef(8 /* END_PRICE */);
|
|
5747
|
+
const lastQuantityInputType = React3.useRef(0 /* NONE */);
|
|
4880
5748
|
const formatQty = () => {
|
|
4881
5749
|
if (base_tick < 1 || // scaled order should not format quantity, because it is total quantity
|
|
4882
5750
|
order_type === types.OrderType.SCALED || !order_quantity) {
|
|
@@ -4923,9 +5791,9 @@ function useFocusAndBlur(props) {
|
|
|
4923
5791
|
function usePriceInputContainer({
|
|
4924
5792
|
order_type_ext
|
|
4925
5793
|
}) {
|
|
4926
|
-
const [priceInputContainerWidth, setPriceInputContainerWidth] =
|
|
4927
|
-
const priceInputContainerRef =
|
|
4928
|
-
|
|
5794
|
+
const [priceInputContainerWidth, setPriceInputContainerWidth] = React3.useState(0);
|
|
5795
|
+
const priceInputContainerRef = React3.useRef(null);
|
|
5796
|
+
React3.useEffect(() => {
|
|
4929
5797
|
const element = priceInputContainerRef.current;
|
|
4930
5798
|
if (!element) {
|
|
4931
5799
|
return;
|
|
@@ -4972,18 +5840,21 @@ var useOrderEntryScript = (inputs) => {
|
|
|
4972
5840
|
defaultSoundValue ?? null
|
|
4973
5841
|
);
|
|
4974
5842
|
const canTrade = reactApp.useCanTrade();
|
|
5843
|
+
const { marginMode } = hooks.useMarginModeBySymbol(symbol);
|
|
4975
5844
|
const {
|
|
4976
5845
|
formattedOrder,
|
|
4977
5846
|
setValue,
|
|
4978
5847
|
setValues: setOrderValues,
|
|
4979
5848
|
symbolInfo,
|
|
5849
|
+
symbolLeverage,
|
|
4980
5850
|
...state
|
|
4981
5851
|
} = hooks.useOrderEntry(symbol, {
|
|
4982
5852
|
initialOrder: {
|
|
4983
5853
|
symbol,
|
|
4984
5854
|
order_type: localOrderType,
|
|
4985
5855
|
position_type: types.PositionType.PARTIAL,
|
|
4986
|
-
side: localOrderSide
|
|
5856
|
+
side: localOrderSide,
|
|
5857
|
+
margin_mode: marginMode
|
|
4987
5858
|
}
|
|
4988
5859
|
});
|
|
4989
5860
|
const [tpslSwitch, setTpslSwitch] = hooks.useLocalStorage(
|
|
@@ -4992,10 +5863,10 @@ var useOrderEntryScript = (inputs) => {
|
|
|
4992
5863
|
);
|
|
4993
5864
|
const { currentLeverage } = hooks.useMarginRatio();
|
|
4994
5865
|
const ee = hooks.useEventEmitter();
|
|
4995
|
-
const triggerPriceInputRef =
|
|
4996
|
-
const priceInputRef =
|
|
4997
|
-
const activatedPriceInputRef =
|
|
4998
|
-
const lastUserActiveTimeRef =
|
|
5866
|
+
const triggerPriceInputRef = React3.useRef(null);
|
|
5867
|
+
const priceInputRef = React3.useRef(null);
|
|
5868
|
+
const activatedPriceInputRef = React3.useRef(null);
|
|
5869
|
+
const lastUserActiveTimeRef = React3.useRef(Date.now());
|
|
4999
5870
|
const { bboStatus, bboType, setBBOType, onBBOChange, toggleBBO } = useBBOState({
|
|
5000
5871
|
tpslSwitch,
|
|
5001
5872
|
order_type: formattedOrder.order_type,
|
|
@@ -5019,13 +5890,13 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5019
5890
|
setOrderValues({
|
|
5020
5891
|
tp_trigger_price: "",
|
|
5021
5892
|
sl_trigger_price: "",
|
|
5022
|
-
position_type: types.PositionType.
|
|
5893
|
+
position_type: types.PositionType.PARTIAL
|
|
5023
5894
|
});
|
|
5024
5895
|
};
|
|
5025
5896
|
const enableTP_SL = () => {
|
|
5026
5897
|
setOrderValues({
|
|
5027
5898
|
order_type_ext: void 0,
|
|
5028
|
-
position_type: types.PositionType.
|
|
5899
|
+
position_type: types.PositionType.PARTIAL
|
|
5029
5900
|
});
|
|
5030
5901
|
};
|
|
5031
5902
|
const setOrderValue = hooks.useMemoizedFn(
|
|
@@ -5058,13 +5929,18 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5058
5929
|
return;
|
|
5059
5930
|
}
|
|
5060
5931
|
if (key === "order_type" && value === types.OrderType.SCALED) {
|
|
5061
|
-
|
|
5932
|
+
const data = {
|
|
5062
5933
|
distribution_type: types.DistributionType.FLAT,
|
|
5063
5934
|
[key]: value
|
|
5064
|
-
}
|
|
5935
|
+
};
|
|
5936
|
+
setOrderValues(data);
|
|
5065
5937
|
return;
|
|
5066
5938
|
}
|
|
5067
|
-
setValue(
|
|
5939
|
+
setValue(
|
|
5940
|
+
key,
|
|
5941
|
+
value,
|
|
5942
|
+
options2
|
|
5943
|
+
);
|
|
5068
5944
|
}
|
|
5069
5945
|
);
|
|
5070
5946
|
const onTPSLSwitchChanged = (state2) => {
|
|
@@ -5075,7 +5951,7 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5075
5951
|
cancelTP_SL();
|
|
5076
5952
|
}
|
|
5077
5953
|
};
|
|
5078
|
-
|
|
5954
|
+
React3.useEffect(() => {
|
|
5079
5955
|
const updateOrderPrice = (price) => {
|
|
5080
5956
|
setValue("order_price", price);
|
|
5081
5957
|
};
|
|
@@ -5084,7 +5960,7 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5084
5960
|
ee.off("update:orderPrice", updateOrderPrice);
|
|
5085
5961
|
};
|
|
5086
5962
|
}, []);
|
|
5087
|
-
|
|
5963
|
+
React3.useEffect(() => {
|
|
5088
5964
|
const focusInputElement = (target) => {
|
|
5089
5965
|
requestAnimationFrame(() => {
|
|
5090
5966
|
target?.focus();
|
|
@@ -5148,12 +6024,12 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5148
6024
|
ee.off("orderbook:item:click", orderBookItemClickHandler);
|
|
5149
6025
|
};
|
|
5150
6026
|
}, [formattedOrder, symbolInfo]);
|
|
5151
|
-
|
|
6027
|
+
React3.useEffect(() => {
|
|
5152
6028
|
state.reset();
|
|
5153
6029
|
state.resetMetaState();
|
|
5154
6030
|
lastQuantityInputType.current = 0 /* NONE */;
|
|
5155
6031
|
}, [symbol]);
|
|
5156
|
-
|
|
6032
|
+
React3.useEffect(() => {
|
|
5157
6033
|
if (formattedOrder.order_type === types.OrderType.SCALED && !formattedOrder.distribution_type) {
|
|
5158
6034
|
setValue("distribution_type", types.DistributionType.FLAT);
|
|
5159
6035
|
}
|
|
@@ -5182,24 +6058,24 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5182
6058
|
currentPosition: state.currentPosition,
|
|
5183
6059
|
orderQuantity: Number(formattedOrder.order_quantity)
|
|
5184
6060
|
});
|
|
5185
|
-
|
|
6061
|
+
React3.useEffect(() => {
|
|
5186
6062
|
if (formattedOrder.reduce_only) {
|
|
5187
6063
|
setTpslSwitch(false);
|
|
5188
6064
|
}
|
|
5189
6065
|
}, [formattedOrder.reduce_only]);
|
|
5190
|
-
|
|
6066
|
+
React3.useEffect(() => {
|
|
5191
6067
|
if (tpslSwitch) {
|
|
5192
6068
|
setOrderValue("reduce_only", false);
|
|
5193
6069
|
}
|
|
5194
6070
|
}, [tpslSwitch]);
|
|
5195
|
-
|
|
6071
|
+
React3.useEffect(() => {
|
|
5196
6072
|
lastUserActiveTimeRef.current = Date.now();
|
|
5197
6073
|
}, [
|
|
5198
6074
|
formattedOrder.order_price,
|
|
5199
6075
|
formattedOrder.order_quantity,
|
|
5200
6076
|
formattedOrder.side
|
|
5201
6077
|
]);
|
|
5202
|
-
|
|
6078
|
+
React3.useEffect(() => {
|
|
5203
6079
|
const lastActive = lastUserActiveTimeRef.current;
|
|
5204
6080
|
const now = Date.now();
|
|
5205
6081
|
const isUserActive = now - lastActive <= ORDER_ENTRY_EST_LIQ_ACTIVE_WINDOW_MS;
|
|
@@ -5209,6 +6085,9 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5209
6085
|
isUserActive
|
|
5210
6086
|
});
|
|
5211
6087
|
}, [ee, symbol, state.estLiqPrice]);
|
|
6088
|
+
React3.useEffect(() => {
|
|
6089
|
+
setOrderValue("margin_mode", marginMode);
|
|
6090
|
+
}, [marginMode]);
|
|
5212
6091
|
return {
|
|
5213
6092
|
...state,
|
|
5214
6093
|
slPriceError: slPriceError ?? void 0,
|
|
@@ -5218,7 +6097,11 @@ var useOrderEntryScript = (inputs) => {
|
|
|
5218
6097
|
formattedOrder,
|
|
5219
6098
|
setOrderValue,
|
|
5220
6099
|
setOrderValues,
|
|
6100
|
+
// account-level leverage (for other consumers)
|
|
5221
6101
|
currentLeverage,
|
|
6102
|
+
// symbol-level leverage & margin mode for this order entry
|
|
6103
|
+
symbolLeverage,
|
|
6104
|
+
marginMode,
|
|
5222
6105
|
// cancelTP_SL,
|
|
5223
6106
|
// enableTP_SL,
|
|
5224
6107
|
tpslSwitch,
|