@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.mjs CHANGED
@@ -2042,6 +2042,7 @@ var OrderTypeSelect = (props) => {
2042
2042
  [OrderType.TRAILING_STOP]: t("orderEntry.orderType.trailingStop")
2043
2043
  };
2044
2044
  }, [t]);
2045
+ const mobileOptions = useMemo(() => allOptions, [allOptions]);
2045
2046
  if (!isMobile) {
2046
2047
  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";
2047
2048
  const selectedButtonClassName = cn(
@@ -2140,7 +2141,6 @@ var OrderTypeSelect = (props) => {
2140
2141
  }
2141
2142
  );
2142
2143
  }
2143
- const mobileOptions = useMemo(() => allOptions, [allOptions]);
2144
2144
  const handleMobileValueChange = (value) => {
2145
2145
  if (marketOrderDisabled && value === OrderType.MARKET && marketOrderDisabledTooltip) {
2146
2146
  modal.alert({
@@ -4780,6 +4780,10 @@ var usePNLInputBuilder = (props) => {
4780
4780
  return `${type.toLowerCase()}_offset`;
4781
4781
  case "Offset%" /* PERCENTAGE */:
4782
4782
  return `${type.toLowerCase()}_offset_percentage`;
4783
+ case "OffsetFromMark" /* OFFSET_FROM_MARK */:
4784
+ return `${type.toLowerCase()}_offset_from_mark`;
4785
+ case "PercentageFromMark" /* PERCENTAGE_FROM_MARK */:
4786
+ return `${type.toLowerCase()}_offset_percentage_from_mark`;
4783
4787
  default:
4784
4788
  return `${type.toLowerCase()}_pnl`;
4785
4789
  }
@@ -4806,17 +4810,32 @@ var usePNLInputBuilder = (props) => {
4806
4810
  testId: `${"Offset" /* OFFSET */}_mneu_item`
4807
4811
  },
4808
4812
  {
4809
- label: `${t("tpsl.offset")}%`,
4813
+ label: t("tpsl.offsetPercent"),
4810
4814
  value: "Offset%" /* PERCENTAGE */,
4811
4815
  testId: `${"Offset%" /* PERCENTAGE */}_menu_item`
4816
+ },
4817
+ {
4818
+ // @ts-ignore
4819
+ label: t("tpsl.offsetMark"),
4820
+ value: "OffsetFromMark" /* OFFSET_FROM_MARK */,
4821
+ testId: `${"OffsetFromMark" /* OFFSET_FROM_MARK */}_menu_item`
4822
+ },
4823
+ {
4824
+ // @ts-ignore
4825
+ label: t("tpsl.offsetPercentMark"),
4826
+ value: "PercentageFromMark" /* PERCENTAGE_FROM_MARK */,
4827
+ testId: `${"PercentageFromMark" /* PERCENTAGE_FROM_MARK */}_menu_item`
4812
4828
  }
4813
4829
  ];
4814
4830
  }, [t]);
4815
4831
  const modeLabelMap = useMemo(() => {
4816
4832
  return {
4817
4833
  ["PnL" /* PnL */]: t("tpsl.pnl"),
4818
- ["Offset" /* OFFSET */]: t("tpsl.offset"),
4819
- ["Offset%" /* PERCENTAGE */]: `${t("tpsl.offset")}%`
4834
+ ["Offset" /* OFFSET */]: t("tpsl.offsetHolder"),
4835
+ ["Offset%" /* PERCENTAGE */]: `${t("tpsl.offsetHolder")}`,
4836
+ // Extend locale keys; not yet in LocaleMessages typings
4837
+ ["OffsetFromMark" /* OFFSET_FROM_MARK */]: t("tpsl.offsetHolder"),
4838
+ ["PercentageFromMark" /* PERCENTAGE_FROM_MARK */]: t("tpsl.offsetHolder")
4820
4839
  };
4821
4840
  }, [t]);
4822
4841
  const percentageSuffix = useRef("");
@@ -4844,7 +4863,7 @@ var usePNLInputBuilder = (props) => {
4844
4863
  value = value.startsWith("-") ? value : "-" + value;
4845
4864
  }
4846
4865
  if (value === "" || value === "-") return "";
4847
- if (mode === "Offset%" /* PERCENTAGE */) {
4866
+ if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
4848
4867
  let normalized = value.replace(
4849
4868
  new RegExp(percentageSuffix.current.replace(".", "\\.") + "$"),
4850
4869
  ""
@@ -4854,7 +4873,7 @@ var usePNLInputBuilder = (props) => {
4854
4873
  return value;
4855
4874
  }
4856
4875
  return `${new Decimal(normalized).mul(100).todp(2, 4).toString()}${percentageSuffix.current}`;
4857
- } else if (mode === "Offset" /* OFFSET */) {
4876
+ } else if (mode === "Offset" /* OFFSET */ || mode === "OffsetFromMark" /* OFFSET_FROM_MARK */) {
4858
4877
  value = todpIfNeed(value, dp);
4859
4878
  } else ;
4860
4879
  return `${value}`;
@@ -4863,7 +4882,7 @@ var usePNLInputBuilder = (props) => {
4863
4882
  if (/^\-?0{2,}$/.test(value)) {
4864
4883
  return "0";
4865
4884
  }
4866
- if (mode === "Offset%" /* PERCENTAGE */) {
4885
+ if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
4867
4886
  if (value !== "") {
4868
4887
  value = todpIfNeed(value, 2);
4869
4888
  const endStr = value.match(/\.0{0,2}$/);
@@ -4922,21 +4941,28 @@ var PNLInput = (props) => {
4922
4941
  setFocus
4923
4942
  } = props;
4924
4943
  const [prefix, setPrefix] = useState(mode);
4944
+ const isPercentageMode = mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */;
4925
4945
  const [placeholder, setPlaceholder] = useState(
4926
- mode === "Offset%" /* PERCENTAGE */ ? "%" : quote
4946
+ isPercentageMode ? "%" : quote
4927
4947
  );
4928
4948
  useEffect(() => {
4929
4949
  setPrefix(mode);
4930
- setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
4931
- }, [mode]);
4950
+ setPlaceholder(isPercentageMode ? "%" : quote);
4951
+ }, [mode, isPercentageMode, quote]);
4932
4952
  useEffect(() => {
4933
4953
  setPrefix(!!value ? "" : mode);
4934
4954
  }, [value]);
4935
- const id = useMemo(() => `${type.toLowerCase()}_${mode.toLowerCase()}`, []);
4955
+ const id = useMemo(
4956
+ () => `${type.toLowerCase()}_${mode.toLowerCase()}`,
4957
+ [type, mode]
4958
+ );
4959
+ const prefixLabel = prefix === "" ? "" : String(
4960
+ modeLabelMap[prefix] ?? prefix ?? ""
4961
+ );
4936
4962
  return /* @__PURE__ */ jsx(
4937
4963
  Input.tooltip,
4938
4964
  {
4939
- prefix: modeLabelMap[prefix] || prefix,
4965
+ prefix: prefixLabel,
4940
4966
  size: "md",
4941
4967
  placeholder,
4942
4968
  id,
@@ -4973,11 +4999,11 @@ var PNLInput = (props) => {
4973
4999
  },
4974
5000
  onBlur: () => {
4975
5001
  setPrefix(!!value ? "" : mode);
4976
- setPlaceholder(mode === "Offset%" /* PERCENTAGE */ ? "%" : quote);
5002
+ setPlaceholder(isPercentageMode ? "%" : quote);
4977
5003
  onBlur();
4978
5004
  },
4979
5005
  suffix: /* @__PURE__ */ jsxs(Fragment, { children: [
4980
- mode === "Offset%" /* PERCENTAGE */ && !!value && /* @__PURE__ */ jsx(Text, { size: "2xs", color: "inherit", className: "oui-ml-[2px]", children: "%" }),
5006
+ isPercentageMode && !!value && /* @__PURE__ */ jsx(Text, { size: "2xs", color: "inherit", className: "oui-ml-[2px]", children: "%" }),
4981
5007
  /* @__PURE__ */ jsx(
4982
5008
  PNLMenus,
4983
5009
  {
@@ -5397,6 +5423,8 @@ var TPSLInputRow = (props) => {
5397
5423
  PnL: props.values.PnL,
5398
5424
  Offset: props.values.Offset,
5399
5425
  "Offset%": props.values["Offset%"],
5426
+ OffsetFromMark: props.values.OffsetFromMark,
5427
+ PercentageFromMark: props.values.PercentageFromMark,
5400
5428
  ROI: props.values.ROI
5401
5429
  }
5402
5430
  }
@@ -5616,6 +5644,8 @@ var OrderEntry = (props) => {
5616
5644
  tp_pnl: order.tp_pnl,
5617
5645
  tp_offset: order.tp_offset,
5618
5646
  tp_offset_percentage: order.tp_offset_percentage,
5647
+ tp_offset_from_mark: order.tp_offset_from_mark,
5648
+ tp_offset_percentage_from_mark: order.tp_offset_percentage_from_mark,
5619
5649
  tp_ROI: order.tp_ROI,
5620
5650
  tp_trigger_price: order.tp_trigger_price,
5621
5651
  tp_order_price: order.tp_order_price,
@@ -5625,6 +5655,8 @@ var OrderEntry = (props) => {
5625
5655
  sl_pnl: order.sl_pnl,
5626
5656
  sl_offset: order.sl_offset,
5627
5657
  sl_offset_percentage: order.sl_offset_percentage,
5658
+ sl_offset_from_mark: order.sl_offset_from_mark,
5659
+ sl_offset_percentage_from_mark: order.sl_offset_percentage_from_mark,
5628
5660
  sl_ROI: order.sl_ROI
5629
5661
  });
5630
5662
  setShowTPSLAdvanced(false);
@@ -5641,6 +5673,14 @@ var OrderEntry = (props) => {
5641
5673
  sl_order_type: OrderType.MARKET,
5642
5674
  tp_pnl: void 0,
5643
5675
  sl_pnl: void 0,
5676
+ tp_offset: void 0,
5677
+ tp_offset_percentage: void 0,
5678
+ tp_offset_from_mark: void 0,
5679
+ tp_offset_percentage_from_mark: void 0,
5680
+ sl_offset: void 0,
5681
+ sl_offset_percentage: void 0,
5682
+ sl_offset_from_mark: void 0,
5683
+ sl_offset_percentage_from_mark: void 0,
5644
5684
  position_type: PositionType.FULL
5645
5685
  });
5646
5686
  };
@@ -5818,6 +5858,8 @@ var OrderEntry = (props) => {
5818
5858
  PnL: formattedOrder.tp_pnl ?? "",
5819
5859
  Offset: formattedOrder.tp_offset ?? "",
5820
5860
  "Offset%": formattedOrder.tp_offset_percentage ?? "",
5861
+ OffsetFromMark: formattedOrder.tp_offset_from_mark ?? "",
5862
+ PercentageFromMark: formattedOrder.tp_offset_percentage_from_mark ?? "",
5821
5863
  ROI: formattedOrder.tp_ROI ?? ""
5822
5864
  },
5823
5865
  sl: {
@@ -5825,6 +5867,8 @@ var OrderEntry = (props) => {
5825
5867
  PnL: formattedOrder.sl_pnl ?? "",
5826
5868
  Offset: formattedOrder.sl_offset ?? "",
5827
5869
  "Offset%": formattedOrder.sl_offset_percentage ?? "",
5870
+ OffsetFromMark: formattedOrder.sl_offset_from_mark ?? "",
5871
+ PercentageFromMark: formattedOrder.sl_offset_percentage_from_mark ?? "",
5828
5872
  ROI: formattedOrder.sl_ROI ?? ""
5829
5873
  }
5830
5874
  },
@@ -6341,9 +6385,22 @@ var useOrderEntryScript = (inputs) => {
6341
6385
  const { priceInputContainerRef, priceInputContainerWidth } = usePriceInputContainer({
6342
6386
  order_type_ext: formattedOrder.order_type_ext
6343
6387
  });
6388
+ const effectiveEstLiqPriceForSlCheck = useMemo(() => {
6389
+ const estLiqPrice = state.estLiqPrice;
6390
+ if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
6391
+ return null;
6392
+ }
6393
+ if (formattedOrder.side === OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === OrderSide.SELL && estLiqPrice < state.markPrice) {
6394
+ return null;
6395
+ }
6396
+ if (!Number.isFinite(estLiqPrice) || estLiqPrice <= 0) {
6397
+ return null;
6398
+ }
6399
+ return estLiqPrice;
6400
+ }, [state.estLiqPrice, state.markPrice, formattedOrder.side]);
6344
6401
  const slPriceError = useTpslPriceChecker({
6345
6402
  slPrice: formattedOrder.sl_trigger_price,
6346
- liqPrice: state.estLiqPrice,
6403
+ liqPrice: effectiveEstLiqPriceForSlCheck,
6347
6404
  side: formattedOrder.side,
6348
6405
  markPrice: state.markPrice,
6349
6406
  currentPosition: state.currentPosition,
@@ -6360,12 +6417,7 @@ var useOrderEntryScript = (inputs) => {
6360
6417
  }
6361
6418
  }, [tpslSwitch]);
6362
6419
  useEffect(() => {
6363
- let estLiqPrice = state.estLiqPrice;
6364
- if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
6365
- estLiqPrice = null;
6366
- } else if (formattedOrder.side === OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === OrderSide.SELL && estLiqPrice < state.markPrice) {
6367
- estLiqPrice = null;
6368
- }
6420
+ const estLiqPrice = effectiveEstLiqPriceForSlCheck;
6369
6421
  const lastActive = lastUserActiveTimeRef.current;
6370
6422
  const now = Date.now();
6371
6423
  const isUserActive = now - lastActive <= ORDER_ENTRY_EST_LIQ_ACTIVE_WINDOW_MS;
@@ -6374,7 +6426,7 @@ var useOrderEntryScript = (inputs) => {
6374
6426
  estLiqPrice,
6375
6427
  isUserActive
6376
6428
  });
6377
- }, [ee, symbol, state.estLiqPrice, state.markPrice, formattedOrder.side]);
6429
+ }, [ee, symbol, effectiveEstLiqPriceForSlCheck]);
6378
6430
  useEffect(() => {
6379
6431
  setOrderValue("margin_mode", marginMode);
6380
6432
  }, [marginMode]);