@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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React2 = require('react');
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 React2__default = /*#__PURE__*/_interopDefault(React2);
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
- React2.useEffect(() => {
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] = React2.useState(false);
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] = React2.useState(defaultPath);
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 = React2.forwardRef((props, ref) => {
608
+ var SlippageEditor = React3.forwardRef((props, ref) => {
609
609
  const { t } = i18n.useTranslation();
610
- const [value, setValue] = React2.useState();
611
- const [customValue, setCustomValue] = React2.useState("");
612
- const [error, setError] = React2.useState(void 0);
613
- React2.useImperativeHandle(ref, () => ({
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
- React2.useEffect(() => {
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 = React2.useRef(null);
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 = React2.useCallback(async () => {
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
- const state = useLTVTooltipScript();
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 = React2.useMemo(() => {
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 = positions?.[0];
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 = React2.useMemo(() => {
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 = React2.memo((props) => {
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 = React2.useMemo(() => {
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 = React2.forwardRef(
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] = React2.useState([0, 0]);
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
- React2.useEffect(() => {
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 = React2.useMemo(() => {
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 = React2.useMemo(() => {
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 options2 = React2.useMemo(() => {
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 displayLabelMap = React2.useMemo(() => {
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: options2,
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-6 oui-border-line"
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 = options2.find((o) => o.value === value);
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
- ui.Text,
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
- size: "xs",
1915
- color: props.canTrade ? props.side === types.OrderSide.BUY ? "buy" : "sell" : void 0,
1916
- children: label
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
- size: "md"
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 { maxLeverage } = hooks.useSymbolLeverage(symbol);
1928
- const curLeverage = symbolLeverage || maxLeverage;
1929
- const showModal = () => {
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
- ui.Flex,
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-rounded oui-border oui-border-line oui-bg-base-6",
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
- onClick: showModal,
2783
+ "data-testid": "oui-testid-orderEntry-margin-leverage",
1950
2784
  children: [
1951
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Cross" }),
1952
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, unit: "X", children: curLeverage })
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 = React2.createContext(
2906
+ var OrderEntryContext = React3.createContext(
2041
2907
  {}
2042
2908
  );
2043
2909
  var useOrderEntryContext = () => {
2044
- return React2.useContext(OrderEntryContext);
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 = React2.useMemo(() => {
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 = React2.forwardRef(
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 = React2.useMemo(
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 = React2.memo((props) => {
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 = React2.memo((props) => {
3255
+ var TotalTypeSelect = React3.memo((props) => {
2390
3256
  const { t } = i18n.useTranslation();
2391
- const options2 = React2.useMemo(() => {
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 = React2.memo((props) => {
3291
+ var TotalInput = React3.memo((props) => {
2426
3292
  const { t } = i18n.useTranslation();
2427
3293
  const { total } = props;
2428
- const [margin, setMargin] = React2.useState("");
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
- React2.useEffect(() => {
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 = React2.memo((props) => {
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 = React2.memo((props) => {
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] = React2.useState(types.DistributionType.FLAT);
2574
- React2.useEffect(() => {
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 = React2.useMemo(() => {
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 = React2.useMemo(() => {
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 = React2.useMemo(() => {
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 = React2.memo((props) => {
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 = React2.useMemo(() => {
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 = React2.memo((props) => {
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 = React2.memo((props) => {
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 = React2.memo((props) => {
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 = React2.memo((props) => {
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 = React2.memo((props) => {
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 = React2.memo(
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 = React2.memo(
4172
+ var TrailingCallbackSelect = React3.memo(
3307
4173
  (props) => {
3308
4174
  const { quote } = props;
3309
- const options2 = React2.useMemo(() => {
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 = React2.memo(
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 = React2.useRef();
3356
- const lastCallbackRateRef = React2.useRef();
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 = React2.useCallback(
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 = React2.memo((props) => {
4381
+ var QuantitySlider = React3.memo((props) => {
3516
4382
  const { canTrade, side, order_quantity, maxQty } = props;
3517
- const [sliderValue, setSliderValue] = React2.useState(0);
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 = React2.useMemo(
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 = React2.useMemo(() => {
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
- React2.useEffect(() => {
4408
+ React3.useEffect(() => {
3543
4409
  if (lastQuantityInputType.current === 4 /* QUANTITY_SLIDER */) {
3544
4410
  sliderToQuantity(sliderValue);
3545
4411
  }
3546
4412
  }, [sliderValue, maxQty]);
3547
- React2.useEffect(() => {
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 = React2.createContext(
4524
+ var PnlInputContext = React3.createContext(
3659
4525
  {}
3660
4526
  );
3661
4527
  var usePnlInputContext = () => {
3662
- return React2.useContext(PnlInputContext);
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] = React2.useState(true);
4535
+ const [focus, setFocus] = React3.useState(true);
3670
4536
  const { mode, setMode, tipsEle } = usePnlInputContext();
3671
- const [tipVisible, setTipVisible] = React2.useState(false);
3672
- const [isFocused, setIsFocused] = React2.useState(false);
3673
- const key = React2.useMemo(() => {
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] = React2.useState(
4549
+ const [innerValue, setInnerValue] = React3.useState(
3684
4550
  values[mode]
3685
4551
  );
3686
- React2.useEffect(() => {
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 = React2.useMemo(() => {
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 = React2.useMemo(() => {
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 = React2.useRef("");
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] = React2.useState(mode);
3815
- const [placeholder, setPlaceholder] = React2.useState(
4680
+ const [prefix, setPrefix] = React3.useState(mode);
4681
+ const [placeholder, setPlaceholder] = React3.useState(
3816
4682
  mode === "Offset%" /* PERCENTAGE */ ? "%" : quote
3817
4683
  );
3818
- React2.useEffect(() => {
4684
+ React3.useEffect(() => {
3819
4685
  setPrefix(mode);
3820
4686
  setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
3821
4687
  }, [mode]);
3822
- React2.useEffect(() => {
4688
+ React3.useEffect(() => {
3823
4689
  setPrefix(!!value ? "" : mode);
3824
4690
  }, [value]);
3825
- const id = React2.useMemo(() => `${type.toLowerCase()}_${mode.toLowerCase()}`, []);
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 = React2.useMemo(() => {
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 = React2.useMemo(() => {
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 = React2__default.default.useRef(null);
4819
+ const tpslFormRef = React3__default.default.useRef(null);
3954
4820
  const { t } = i18n.useTranslation();
3955
4821
  const { isMobile } = ui.useScreen();
3956
- React2.useEffect(() => {
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 = React2__default.default.forwardRef((props, ref) => {
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] = React2.useState(`${props.type} Price`);
4160
- const [placeholder, setPlaceholder] = React2.useState("USDC");
4161
- const [tipVisible, setTipVisible] = React2.useState(false);
4162
- const [isFocused, setIsFocused] = React2.useState(false);
4163
- const [innerValue, setInnerValue] = React2.useState(
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
- React2.useEffect(() => {
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 = React2.useMemo(() => {
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
- React2.useEffect(() => {
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] = React2.useState(false);
5185
+ const [maxQtyConfirmOpen, setMaxQtyConfirmOpen] = React3.useState(false);
4320
5186
  const { t } = i18n.useTranslation();
4321
5187
  const { isMobile } = ui.useScreen();
4322
- const [hasAdvancedTPSLResult, setHasAdvancedTPSLResult] = React2.useState(false);
5188
+ const [hasAdvancedTPSLResult, setHasAdvancedTPSLResult] = React3.useState(false);
4323
5189
  const { errors, validated } = metaState;
4324
- const [errorMsgVisible, setErrorMsgVisible] = React2.useState(false);
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] = React2.useState(false);
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 = React2.useId();
5207
+ const soundAlertId = React3.useId();
4342
5208
  const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(validated ? errors : null);
4343
- const buttonLabel = React2.useMemo(() => {
5209
+ const buttonLabel = React3.useMemo(() => {
4344
5210
  return side === types.OrderSide.BUY ? t("orderEntry.buyLong") : t("orderEntry.sellShort");
4345
5211
  }, [side, t, isMobile]);
4346
- React2.useEffect(() => {
5212
+ React3.useEffect(() => {
4347
5213
  if (validated) {
4348
5214
  setErrorMsgVisible(true);
4349
5215
  }
4350
5216
  }, [validated]);
4351
- React2.useEffect(() => {
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
- React2.useEffect(() => {
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 = React2.useMemo(() => {
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 = React2.useCallback(() => {
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
- React2.useEffect(() => {
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 = React2.useRef(localBBOType);
5690
+ const lastBBOType = React3.useRef(localBBOType);
4823
5691
  const { track } = hooks.useTrack();
4824
- const bboStatus = React2.useMemo(() => {
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
- React2.useEffect(() => {
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
- React2.useEffect(() => {
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 = React2.useRef(0 /* NONE */);
4878
- const lastScaledOrderPriceInput = React2.useRef(8 /* END_PRICE */);
4879
- const lastQuantityInputType = React2.useRef(0 /* NONE */);
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] = React2.useState(0);
4927
- const priceInputContainerRef = React2.useRef(null);
4928
- React2.useEffect(() => {
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 = React2.useRef(null);
4996
- const priceInputRef = React2.useRef(null);
4997
- const activatedPriceInputRef = React2.useRef(null);
4998
- const lastUserActiveTimeRef = React2.useRef(Date.now());
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.FULL
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.FULL
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
- setOrderValues({
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(key, value, options2);
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
- React2.useEffect(() => {
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
- React2.useEffect(() => {
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
- React2.useEffect(() => {
6027
+ React3.useEffect(() => {
5152
6028
  state.reset();
5153
6029
  state.resetMetaState();
5154
6030
  lastQuantityInputType.current = 0 /* NONE */;
5155
6031
  }, [symbol]);
5156
- React2.useEffect(() => {
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
- React2.useEffect(() => {
6061
+ React3.useEffect(() => {
5186
6062
  if (formattedOrder.reduce_only) {
5187
6063
  setTpslSwitch(false);
5188
6064
  }
5189
6065
  }, [formattedOrder.reduce_only]);
5190
- React2.useEffect(() => {
6066
+ React3.useEffect(() => {
5191
6067
  if (tpslSwitch) {
5192
6068
  setOrderValue("reduce_only", false);
5193
6069
  }
5194
6070
  }, [tpslSwitch]);
5195
- React2.useEffect(() => {
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
- React2.useEffect(() => {
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,