@orderly.network/ui-order-entry 2.12.2 → 2.12.3-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
@@ -2048,6 +2048,7 @@ var OrderTypeSelect = (props) => {
2048
2048
  [types.OrderType.TRAILING_STOP]: t("orderEntry.orderType.trailingStop")
2049
2049
  };
2050
2050
  }, [t]);
2051
+ const mobileOptions = React3.useMemo(() => allOptions, [allOptions]);
2051
2052
  if (!isMobile) {
2052
2053
  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";
2053
2054
  const selectedButtonClassName = ui.cn(
@@ -2146,7 +2147,6 @@ var OrderTypeSelect = (props) => {
2146
2147
  }
2147
2148
  );
2148
2149
  }
2149
- const mobileOptions = React3.useMemo(() => allOptions, [allOptions]);
2150
2150
  const handleMobileValueChange = (value) => {
2151
2151
  if (marketOrderDisabled && value === types.OrderType.MARKET && marketOrderDisabledTooltip) {
2152
2152
  ui.modal.alert({
@@ -4786,6 +4786,10 @@ var usePNLInputBuilder = (props) => {
4786
4786
  return `${type.toLowerCase()}_offset`;
4787
4787
  case "Offset%" /* PERCENTAGE */:
4788
4788
  return `${type.toLowerCase()}_offset_percentage`;
4789
+ case "OffsetFromMark" /* OFFSET_FROM_MARK */:
4790
+ return `${type.toLowerCase()}_offset_from_mark`;
4791
+ case "PercentageFromMark" /* PERCENTAGE_FROM_MARK */:
4792
+ return `${type.toLowerCase()}_offset_percentage_from_mark`;
4789
4793
  default:
4790
4794
  return `${type.toLowerCase()}_pnl`;
4791
4795
  }
@@ -4812,17 +4816,32 @@ var usePNLInputBuilder = (props) => {
4812
4816
  testId: `${"Offset" /* OFFSET */}_mneu_item`
4813
4817
  },
4814
4818
  {
4815
- label: `${t("tpsl.offset")}%`,
4819
+ label: t("tpsl.offsetPercent"),
4816
4820
  value: "Offset%" /* PERCENTAGE */,
4817
4821
  testId: `${"Offset%" /* PERCENTAGE */}_menu_item`
4822
+ },
4823
+ {
4824
+ // @ts-ignore
4825
+ label: t("tpsl.offsetMark"),
4826
+ value: "OffsetFromMark" /* OFFSET_FROM_MARK */,
4827
+ testId: `${"OffsetFromMark" /* OFFSET_FROM_MARK */}_menu_item`
4828
+ },
4829
+ {
4830
+ // @ts-ignore
4831
+ label: t("tpsl.offsetPercentMark"),
4832
+ value: "PercentageFromMark" /* PERCENTAGE_FROM_MARK */,
4833
+ testId: `${"PercentageFromMark" /* PERCENTAGE_FROM_MARK */}_menu_item`
4818
4834
  }
4819
4835
  ];
4820
4836
  }, [t]);
4821
4837
  const modeLabelMap = React3.useMemo(() => {
4822
4838
  return {
4823
4839
  ["PnL" /* PnL */]: t("tpsl.pnl"),
4824
- ["Offset" /* OFFSET */]: t("tpsl.offset"),
4825
- ["Offset%" /* PERCENTAGE */]: `${t("tpsl.offset")}%`
4840
+ ["Offset" /* OFFSET */]: t("tpsl.offsetHolder"),
4841
+ ["Offset%" /* PERCENTAGE */]: `${t("tpsl.offsetHolder")}`,
4842
+ // Extend locale keys; not yet in LocaleMessages typings
4843
+ ["OffsetFromMark" /* OFFSET_FROM_MARK */]: t("tpsl.offsetHolder"),
4844
+ ["PercentageFromMark" /* PERCENTAGE_FROM_MARK */]: t("tpsl.offsetHolder")
4826
4845
  };
4827
4846
  }, [t]);
4828
4847
  const percentageSuffix = React3.useRef("");
@@ -4850,7 +4869,7 @@ var usePNLInputBuilder = (props) => {
4850
4869
  value = value.startsWith("-") ? value : "-" + value;
4851
4870
  }
4852
4871
  if (value === "" || value === "-") return "";
4853
- if (mode === "Offset%" /* PERCENTAGE */) {
4872
+ if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
4854
4873
  let normalized = value.replace(
4855
4874
  new RegExp(percentageSuffix.current.replace(".", "\\.") + "$"),
4856
4875
  ""
@@ -4860,7 +4879,7 @@ var usePNLInputBuilder = (props) => {
4860
4879
  return value;
4861
4880
  }
4862
4881
  return `${new utils.Decimal(normalized).mul(100).todp(2, 4).toString()}${percentageSuffix.current}`;
4863
- } else if (mode === "Offset" /* OFFSET */) {
4882
+ } else if (mode === "Offset" /* OFFSET */ || mode === "OffsetFromMark" /* OFFSET_FROM_MARK */) {
4864
4883
  value = utils.todpIfNeed(value, dp);
4865
4884
  } else ;
4866
4885
  return `${value}`;
@@ -4869,7 +4888,7 @@ var usePNLInputBuilder = (props) => {
4869
4888
  if (/^\-?0{2,}$/.test(value)) {
4870
4889
  return "0";
4871
4890
  }
4872
- if (mode === "Offset%" /* PERCENTAGE */) {
4891
+ if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
4873
4892
  if (value !== "") {
4874
4893
  value = utils.todpIfNeed(value, 2);
4875
4894
  const endStr = value.match(/\.0{0,2}$/);
@@ -4928,21 +4947,28 @@ var PNLInput = (props) => {
4928
4947
  setFocus
4929
4948
  } = props;
4930
4949
  const [prefix, setPrefix] = React3.useState(mode);
4950
+ const isPercentageMode = mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */;
4931
4951
  const [placeholder, setPlaceholder] = React3.useState(
4932
- mode === "Offset%" /* PERCENTAGE */ ? "%" : quote
4952
+ isPercentageMode ? "%" : quote
4933
4953
  );
4934
4954
  React3.useEffect(() => {
4935
4955
  setPrefix(mode);
4936
- setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
4937
- }, [mode]);
4956
+ setPlaceholder(isPercentageMode ? "%" : quote);
4957
+ }, [mode, isPercentageMode, quote]);
4938
4958
  React3.useEffect(() => {
4939
4959
  setPrefix(!!value ? "" : mode);
4940
4960
  }, [value]);
4941
- const id = React3.useMemo(() => `${type.toLowerCase()}_${mode.toLowerCase()}`, []);
4961
+ const id = React3.useMemo(
4962
+ () => `${type.toLowerCase()}_${mode.toLowerCase()}`,
4963
+ [type, mode]
4964
+ );
4965
+ const prefixLabel = prefix === "" ? "" : String(
4966
+ modeLabelMap[prefix] ?? prefix ?? ""
4967
+ );
4942
4968
  return /* @__PURE__ */ jsxRuntime.jsx(
4943
4969
  ui.Input.tooltip,
4944
4970
  {
4945
- prefix: modeLabelMap[prefix] || prefix,
4971
+ prefix: prefixLabel,
4946
4972
  size: "md",
4947
4973
  placeholder,
4948
4974
  id,
@@ -4979,11 +5005,11 @@ var PNLInput = (props) => {
4979
5005
  },
4980
5006
  onBlur: () => {
4981
5007
  setPrefix(!!value ? "" : mode);
4982
- setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
5008
+ setPlaceholder(isPercentageMode ? "%" : quote);
4983
5009
  onBlur();
4984
5010
  },
4985
5011
  suffix: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4986
- mode === "Offset%" /* PERCENTAGE */ && !!value && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", color: "inherit", className: "oui-ml-[2px]", children: "%" }),
5012
+ isPercentageMode && !!value && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", color: "inherit", className: "oui-ml-[2px]", children: "%" }),
4987
5013
  /* @__PURE__ */ jsxRuntime.jsx(
4988
5014
  PNLMenus,
4989
5015
  {
@@ -5403,6 +5429,8 @@ var TPSLInputRow = (props) => {
5403
5429
  PnL: props.values.PnL,
5404
5430
  Offset: props.values.Offset,
5405
5431
  "Offset%": props.values["Offset%"],
5432
+ OffsetFromMark: props.values.OffsetFromMark,
5433
+ PercentageFromMark: props.values.PercentageFromMark,
5406
5434
  ROI: props.values.ROI
5407
5435
  }
5408
5436
  }
@@ -5622,6 +5650,8 @@ var OrderEntry = (props) => {
5622
5650
  tp_pnl: order.tp_pnl,
5623
5651
  tp_offset: order.tp_offset,
5624
5652
  tp_offset_percentage: order.tp_offset_percentage,
5653
+ tp_offset_from_mark: order.tp_offset_from_mark,
5654
+ tp_offset_percentage_from_mark: order.tp_offset_percentage_from_mark,
5625
5655
  tp_ROI: order.tp_ROI,
5626
5656
  tp_trigger_price: order.tp_trigger_price,
5627
5657
  tp_order_price: order.tp_order_price,
@@ -5631,6 +5661,8 @@ var OrderEntry = (props) => {
5631
5661
  sl_pnl: order.sl_pnl,
5632
5662
  sl_offset: order.sl_offset,
5633
5663
  sl_offset_percentage: order.sl_offset_percentage,
5664
+ sl_offset_from_mark: order.sl_offset_from_mark,
5665
+ sl_offset_percentage_from_mark: order.sl_offset_percentage_from_mark,
5634
5666
  sl_ROI: order.sl_ROI
5635
5667
  });
5636
5668
  setShowTPSLAdvanced(false);
@@ -5647,6 +5679,14 @@ var OrderEntry = (props) => {
5647
5679
  sl_order_type: types.OrderType.MARKET,
5648
5680
  tp_pnl: void 0,
5649
5681
  sl_pnl: void 0,
5682
+ tp_offset: void 0,
5683
+ tp_offset_percentage: void 0,
5684
+ tp_offset_from_mark: void 0,
5685
+ tp_offset_percentage_from_mark: void 0,
5686
+ sl_offset: void 0,
5687
+ sl_offset_percentage: void 0,
5688
+ sl_offset_from_mark: void 0,
5689
+ sl_offset_percentage_from_mark: void 0,
5650
5690
  position_type: types.PositionType.FULL
5651
5691
  });
5652
5692
  };
@@ -5824,6 +5864,8 @@ var OrderEntry = (props) => {
5824
5864
  PnL: formattedOrder.tp_pnl ?? "",
5825
5865
  Offset: formattedOrder.tp_offset ?? "",
5826
5866
  "Offset%": formattedOrder.tp_offset_percentage ?? "",
5867
+ OffsetFromMark: formattedOrder.tp_offset_from_mark ?? "",
5868
+ PercentageFromMark: formattedOrder.tp_offset_percentage_from_mark ?? "",
5827
5869
  ROI: formattedOrder.tp_ROI ?? ""
5828
5870
  },
5829
5871
  sl: {
@@ -5831,6 +5873,8 @@ var OrderEntry = (props) => {
5831
5873
  PnL: formattedOrder.sl_pnl ?? "",
5832
5874
  Offset: formattedOrder.sl_offset ?? "",
5833
5875
  "Offset%": formattedOrder.sl_offset_percentage ?? "",
5876
+ OffsetFromMark: formattedOrder.sl_offset_from_mark ?? "",
5877
+ PercentageFromMark: formattedOrder.sl_offset_percentage_from_mark ?? "",
5834
5878
  ROI: formattedOrder.sl_ROI ?? ""
5835
5879
  }
5836
5880
  },
@@ -6347,9 +6391,22 @@ var useOrderEntryScript = (inputs) => {
6347
6391
  const { priceInputContainerRef, priceInputContainerWidth } = usePriceInputContainer({
6348
6392
  order_type_ext: formattedOrder.order_type_ext
6349
6393
  });
6394
+ const effectiveEstLiqPriceForSlCheck = React3.useMemo(() => {
6395
+ const estLiqPrice = state.estLiqPrice;
6396
+ if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
6397
+ return null;
6398
+ }
6399
+ if (formattedOrder.side === types.OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === types.OrderSide.SELL && estLiqPrice < state.markPrice) {
6400
+ return null;
6401
+ }
6402
+ if (!Number.isFinite(estLiqPrice) || estLiqPrice <= 0) {
6403
+ return null;
6404
+ }
6405
+ return estLiqPrice;
6406
+ }, [state.estLiqPrice, state.markPrice, formattedOrder.side]);
6350
6407
  const slPriceError = hooks.useTpslPriceChecker({
6351
6408
  slPrice: formattedOrder.sl_trigger_price,
6352
- liqPrice: state.estLiqPrice,
6409
+ liqPrice: effectiveEstLiqPriceForSlCheck,
6353
6410
  side: formattedOrder.side,
6354
6411
  markPrice: state.markPrice,
6355
6412
  currentPosition: state.currentPosition,
@@ -6366,12 +6423,7 @@ var useOrderEntryScript = (inputs) => {
6366
6423
  }
6367
6424
  }, [tpslSwitch]);
6368
6425
  React3.useEffect(() => {
6369
- let estLiqPrice = state.estLiqPrice;
6370
- if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
6371
- estLiqPrice = null;
6372
- } else if (formattedOrder.side === types.OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === types.OrderSide.SELL && estLiqPrice < state.markPrice) {
6373
- estLiqPrice = null;
6374
- }
6426
+ const estLiqPrice = effectiveEstLiqPriceForSlCheck;
6375
6427
  const lastActive = lastUserActiveTimeRef.current;
6376
6428
  const now = Date.now();
6377
6429
  const isUserActive = now - lastActive <= ORDER_ENTRY_EST_LIQ_ACTIVE_WINDOW_MS;
@@ -6380,7 +6432,7 @@ var useOrderEntryScript = (inputs) => {
6380
6432
  estLiqPrice,
6381
6433
  isUserActive
6382
6434
  });
6383
- }, [ee, symbol, state.estLiqPrice, state.markPrice, formattedOrder.side]);
6435
+ }, [ee, symbol, effectiveEstLiqPriceForSlCheck]);
6384
6436
  React3.useEffect(() => {
6385
6437
  setOrderValue("margin_mode", marginMode);
6386
6438
  }, [marginMode]);