@orderly.network/ui-order-entry 3.0.0-beta.3 → 3.0.0-beta.4
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 +93 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
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({
|
|
@@ -4866,10 +4866,19 @@ var usePnlInputContext = () => {
|
|
|
4866
4866
|
};
|
|
4867
4867
|
|
|
4868
4868
|
// src/components/pnlInput/useBuilder.script.ts
|
|
4869
|
+
function normalizeSlPnlForStore(raw) {
|
|
4870
|
+
const v = `${raw}`.replace(/,/g, "").trim();
|
|
4871
|
+
if (v === "" || v === "-") return v;
|
|
4872
|
+
const withoutTrailingDot = v.replace(/\.$/, "");
|
|
4873
|
+
const num = Number(withoutTrailingDot);
|
|
4874
|
+
if (!isNaN(num) && num === 0) return "0";
|
|
4875
|
+
if (v.startsWith("-")) return v;
|
|
4876
|
+
return `-${v}`;
|
|
4877
|
+
}
|
|
4869
4878
|
var usePNLInputBuilder = (props) => {
|
|
4870
4879
|
const { type, values, quote_dp } = props;
|
|
4871
4880
|
const { t } = i18n.useTranslation();
|
|
4872
|
-
const [
|
|
4881
|
+
const [, setFocus] = React3.useState(true);
|
|
4873
4882
|
const { mode, setMode, tipsEle } = usePnlInputContext();
|
|
4874
4883
|
const [tipVisible, setTipVisible] = React3.useState(false);
|
|
4875
4884
|
const [isFocused, setIsFocused] = React3.useState(false);
|
|
@@ -4879,10 +4888,14 @@ var usePNLInputBuilder = (props) => {
|
|
|
4879
4888
|
return `${type.toLowerCase()}_offset`;
|
|
4880
4889
|
case "Offset%" /* PERCENTAGE */:
|
|
4881
4890
|
return `${type.toLowerCase()}_offset_percentage`;
|
|
4891
|
+
case "OffsetFromMark" /* OFFSET_FROM_MARK */:
|
|
4892
|
+
return `${type.toLowerCase()}_offset_from_mark`;
|
|
4893
|
+
case "PercentageFromMark" /* PERCENTAGE_FROM_MARK */:
|
|
4894
|
+
return `${type.toLowerCase()}_offset_percentage_from_mark`;
|
|
4882
4895
|
default:
|
|
4883
4896
|
return `${type.toLowerCase()}_pnl`;
|
|
4884
4897
|
}
|
|
4885
|
-
}, [mode]);
|
|
4898
|
+
}, [mode, type]);
|
|
4886
4899
|
const [innerValue, setInnerValue] = React3.useState(
|
|
4887
4900
|
values[mode]
|
|
4888
4901
|
);
|
|
@@ -4905,23 +4918,39 @@ var usePNLInputBuilder = (props) => {
|
|
|
4905
4918
|
testId: `${"Offset" /* OFFSET */}_mneu_item`
|
|
4906
4919
|
},
|
|
4907
4920
|
{
|
|
4908
|
-
label:
|
|
4921
|
+
label: t("tpsl.offsetPercent"),
|
|
4909
4922
|
value: "Offset%" /* PERCENTAGE */,
|
|
4910
4923
|
testId: `${"Offset%" /* PERCENTAGE */}_menu_item`
|
|
4924
|
+
},
|
|
4925
|
+
{
|
|
4926
|
+
// @ts-ignore
|
|
4927
|
+
label: t("tpsl.offsetMark"),
|
|
4928
|
+
value: "OffsetFromMark" /* OFFSET_FROM_MARK */,
|
|
4929
|
+
testId: `${"OffsetFromMark" /* OFFSET_FROM_MARK */}_menu_item`
|
|
4930
|
+
},
|
|
4931
|
+
{
|
|
4932
|
+
// @ts-ignore
|
|
4933
|
+
label: t("tpsl.offsetPercentMark"),
|
|
4934
|
+
value: "PercentageFromMark" /* PERCENTAGE_FROM_MARK */,
|
|
4935
|
+
testId: `${"PercentageFromMark" /* PERCENTAGE_FROM_MARK */}_menu_item`
|
|
4911
4936
|
}
|
|
4912
4937
|
];
|
|
4913
4938
|
}, [t]);
|
|
4914
4939
|
const modeLabelMap = React3.useMemo(() => {
|
|
4915
4940
|
return {
|
|
4916
4941
|
["PnL" /* PnL */]: t("tpsl.pnl"),
|
|
4917
|
-
["Offset" /* OFFSET */]: t("tpsl.
|
|
4918
|
-
["Offset%" /* PERCENTAGE */]: `${t("tpsl.
|
|
4942
|
+
["Offset" /* OFFSET */]: t("tpsl.offsetHolder"),
|
|
4943
|
+
["Offset%" /* PERCENTAGE */]: `${t("tpsl.offsetHolder")}`,
|
|
4944
|
+
// Extend locale keys; not yet in LocaleMessages typings
|
|
4945
|
+
["OffsetFromMark" /* OFFSET_FROM_MARK */]: t("tpsl.offsetHolder"),
|
|
4946
|
+
["PercentageFromMark" /* PERCENTAGE_FROM_MARK */]: t("tpsl.offsetHolder")
|
|
4919
4947
|
};
|
|
4920
4948
|
}, [t]);
|
|
4921
4949
|
const percentageSuffix = React3.useRef("");
|
|
4922
4950
|
const onValueChange = (value) => {
|
|
4923
4951
|
setInnerValue(value);
|
|
4924
|
-
|
|
4952
|
+
const outgoing = key === "sl_pnl" ? normalizeSlPnlForStore(value) : value;
|
|
4953
|
+
props.onChange(key, outgoing);
|
|
4925
4954
|
};
|
|
4926
4955
|
const onFocus = () => {
|
|
4927
4956
|
setTipVisible(true);
|
|
@@ -4930,20 +4959,19 @@ var usePNLInputBuilder = (props) => {
|
|
|
4930
4959
|
const onBlur = () => {
|
|
4931
4960
|
setTipVisible(false);
|
|
4932
4961
|
setIsFocused(false);
|
|
4933
|
-
|
|
4962
|
+
const outgoing = key === "sl_pnl" ? normalizeSlPnlForStore(innerValue) : innerValue;
|
|
4963
|
+
props.onChange(key, outgoing);
|
|
4934
4964
|
};
|
|
4935
4965
|
const formatter = (options2) => {
|
|
4936
4966
|
const { dp = 2 } = options2;
|
|
4937
4967
|
return {
|
|
4938
4968
|
onRenderBefore: (value, options3) => {
|
|
4939
4969
|
value = `${value}`;
|
|
4940
|
-
if (
|
|
4941
|
-
|
|
4942
|
-
value = value.startsWith("-") ? value : "-" + value;
|
|
4943
|
-
}
|
|
4970
|
+
if (type === "SL" && mode === "PnL" /* PnL */) {
|
|
4971
|
+
value = value.startsWith("-") ? value : "-" + value;
|
|
4944
4972
|
}
|
|
4945
4973
|
if (value === "" || value === "-") return "";
|
|
4946
|
-
if (mode === "Offset%" /* PERCENTAGE */) {
|
|
4974
|
+
if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
|
|
4947
4975
|
let normalized = value.replace(
|
|
4948
4976
|
new RegExp(percentageSuffix.current.replace(".", "\\.") + "$"),
|
|
4949
4977
|
""
|
|
@@ -4953,7 +4981,7 @@ var usePNLInputBuilder = (props) => {
|
|
|
4953
4981
|
return value;
|
|
4954
4982
|
}
|
|
4955
4983
|
return `${new utils.Decimal(normalized).mul(100).todp(2, 4).toString()}${percentageSuffix.current}`;
|
|
4956
|
-
} else if (mode === "Offset" /* OFFSET */) {
|
|
4984
|
+
} else if (mode === "Offset" /* OFFSET */ || mode === "OffsetFromMark" /* OFFSET_FROM_MARK */) {
|
|
4957
4985
|
value = utils.todpIfNeed(value, dp);
|
|
4958
4986
|
} else ;
|
|
4959
4987
|
return `${value}`;
|
|
@@ -4962,7 +4990,7 @@ var usePNLInputBuilder = (props) => {
|
|
|
4962
4990
|
if (/^\-?0{2,}$/.test(value)) {
|
|
4963
4991
|
return "0";
|
|
4964
4992
|
}
|
|
4965
|
-
if (mode === "Offset%" /* PERCENTAGE */) {
|
|
4993
|
+
if (mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */) {
|
|
4966
4994
|
if (value !== "") {
|
|
4967
4995
|
value = utils.todpIfNeed(value, 2);
|
|
4968
4996
|
const endStr = value.match(/\.0{0,2}$/);
|
|
@@ -4977,7 +5005,7 @@ var usePNLInputBuilder = (props) => {
|
|
|
4977
5005
|
value = new utils.Decimal(value).div(100).toString();
|
|
4978
5006
|
value = `${value}${percentageSuffix.current}`;
|
|
4979
5007
|
}
|
|
4980
|
-
} else if (mode === "PnL" /* PnL */ && type === "SL"
|
|
5008
|
+
} else if (mode === "PnL" /* PnL */ && type === "SL") {
|
|
4981
5009
|
value = value.startsWith("-") ? value : "-" + value;
|
|
4982
5010
|
} else {
|
|
4983
5011
|
value = utils.todpIfNeed(value, dp);
|
|
@@ -5021,21 +5049,28 @@ var PNLInput = (props) => {
|
|
|
5021
5049
|
setFocus
|
|
5022
5050
|
} = props;
|
|
5023
5051
|
const [prefix, setPrefix] = React3.useState(mode);
|
|
5052
|
+
const isPercentageMode = mode === "Offset%" /* PERCENTAGE */ || mode === "PercentageFromMark" /* PERCENTAGE_FROM_MARK */;
|
|
5024
5053
|
const [placeholder, setPlaceholder] = React3.useState(
|
|
5025
|
-
|
|
5054
|
+
isPercentageMode ? "%" : quote
|
|
5026
5055
|
);
|
|
5027
5056
|
React3.useEffect(() => {
|
|
5028
5057
|
setPrefix(mode);
|
|
5029
|
-
setPlaceholder(
|
|
5030
|
-
}, [mode]);
|
|
5058
|
+
setPlaceholder(isPercentageMode ? "%" : quote);
|
|
5059
|
+
}, [mode, isPercentageMode, quote]);
|
|
5031
5060
|
React3.useEffect(() => {
|
|
5032
5061
|
setPrefix(!!value ? "" : mode);
|
|
5033
5062
|
}, [value]);
|
|
5034
|
-
const id = React3.useMemo(
|
|
5063
|
+
const id = React3.useMemo(
|
|
5064
|
+
() => `${type.toLowerCase()}_${mode.toLowerCase()}`,
|
|
5065
|
+
[type, mode]
|
|
5066
|
+
);
|
|
5067
|
+
const prefixLabel = prefix === "" ? "" : String(
|
|
5068
|
+
modeLabelMap[prefix] ?? prefix ?? ""
|
|
5069
|
+
);
|
|
5035
5070
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5036
5071
|
ui.Input.tooltip,
|
|
5037
5072
|
{
|
|
5038
|
-
prefix:
|
|
5073
|
+
prefix: prefixLabel,
|
|
5039
5074
|
size: "md",
|
|
5040
5075
|
placeholder,
|
|
5041
5076
|
id,
|
|
@@ -5072,11 +5107,11 @@ var PNLInput = (props) => {
|
|
|
5072
5107
|
},
|
|
5073
5108
|
onBlur: () => {
|
|
5074
5109
|
setPrefix(!!value ? "" : mode);
|
|
5075
|
-
setPlaceholder(
|
|
5110
|
+
setPlaceholder(isPercentageMode ? "%" : quote);
|
|
5076
5111
|
onBlur();
|
|
5077
5112
|
},
|
|
5078
5113
|
suffix: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5079
|
-
|
|
5114
|
+
isPercentageMode && !!value && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", color: "inherit", className: "oui-ml-[2px]", children: "%" }),
|
|
5080
5115
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5081
5116
|
PNLMenus,
|
|
5082
5117
|
{
|
|
@@ -5496,6 +5531,8 @@ var TPSLInputRow = (props) => {
|
|
|
5496
5531
|
PnL: props.values.PnL,
|
|
5497
5532
|
Offset: props.values.Offset,
|
|
5498
5533
|
"Offset%": props.values["Offset%"],
|
|
5534
|
+
OffsetFromMark: props.values.OffsetFromMark,
|
|
5535
|
+
PercentageFromMark: props.values.PercentageFromMark,
|
|
5499
5536
|
ROI: props.values.ROI
|
|
5500
5537
|
}
|
|
5501
5538
|
}
|
|
@@ -5715,6 +5752,8 @@ var OrderEntry = (props) => {
|
|
|
5715
5752
|
tp_pnl: order.tp_pnl,
|
|
5716
5753
|
tp_offset: order.tp_offset,
|
|
5717
5754
|
tp_offset_percentage: order.tp_offset_percentage,
|
|
5755
|
+
tp_offset_from_mark: order.tp_offset_from_mark,
|
|
5756
|
+
tp_offset_percentage_from_mark: order.tp_offset_percentage_from_mark,
|
|
5718
5757
|
tp_ROI: order.tp_ROI,
|
|
5719
5758
|
tp_trigger_price: order.tp_trigger_price,
|
|
5720
5759
|
tp_order_price: order.tp_order_price,
|
|
@@ -5724,6 +5763,8 @@ var OrderEntry = (props) => {
|
|
|
5724
5763
|
sl_pnl: order.sl_pnl,
|
|
5725
5764
|
sl_offset: order.sl_offset,
|
|
5726
5765
|
sl_offset_percentage: order.sl_offset_percentage,
|
|
5766
|
+
sl_offset_from_mark: order.sl_offset_from_mark,
|
|
5767
|
+
sl_offset_percentage_from_mark: order.sl_offset_percentage_from_mark,
|
|
5727
5768
|
sl_ROI: order.sl_ROI
|
|
5728
5769
|
});
|
|
5729
5770
|
setShowTPSLAdvanced(false);
|
|
@@ -5740,6 +5781,14 @@ var OrderEntry = (props) => {
|
|
|
5740
5781
|
sl_order_type: types.OrderType.MARKET,
|
|
5741
5782
|
tp_pnl: void 0,
|
|
5742
5783
|
sl_pnl: void 0,
|
|
5784
|
+
tp_offset: void 0,
|
|
5785
|
+
tp_offset_percentage: void 0,
|
|
5786
|
+
tp_offset_from_mark: void 0,
|
|
5787
|
+
tp_offset_percentage_from_mark: void 0,
|
|
5788
|
+
sl_offset: void 0,
|
|
5789
|
+
sl_offset_percentage: void 0,
|
|
5790
|
+
sl_offset_from_mark: void 0,
|
|
5791
|
+
sl_offset_percentage_from_mark: void 0,
|
|
5743
5792
|
position_type: types.PositionType.FULL
|
|
5744
5793
|
});
|
|
5745
5794
|
};
|
|
@@ -5908,6 +5957,8 @@ var OrderEntry = (props) => {
|
|
|
5908
5957
|
PnL: formattedOrder.tp_pnl ?? "",
|
|
5909
5958
|
Offset: formattedOrder.tp_offset ?? "",
|
|
5910
5959
|
"Offset%": formattedOrder.tp_offset_percentage ?? "",
|
|
5960
|
+
OffsetFromMark: formattedOrder.tp_offset_from_mark ?? "",
|
|
5961
|
+
PercentageFromMark: formattedOrder.tp_offset_percentage_from_mark ?? "",
|
|
5911
5962
|
ROI: formattedOrder.tp_ROI ?? ""
|
|
5912
5963
|
},
|
|
5913
5964
|
sl: {
|
|
@@ -5915,6 +5966,8 @@ var OrderEntry = (props) => {
|
|
|
5915
5966
|
PnL: formattedOrder.sl_pnl ?? "",
|
|
5916
5967
|
Offset: formattedOrder.sl_offset ?? "",
|
|
5917
5968
|
"Offset%": formattedOrder.sl_offset_percentage ?? "",
|
|
5969
|
+
OffsetFromMark: formattedOrder.sl_offset_from_mark ?? "",
|
|
5970
|
+
PercentageFromMark: formattedOrder.sl_offset_percentage_from_mark ?? "",
|
|
5918
5971
|
ROI: formattedOrder.sl_ROI ?? ""
|
|
5919
5972
|
}
|
|
5920
5973
|
},
|
|
@@ -6431,10 +6484,24 @@ var useOrderEntryScript = (inputs) => {
|
|
|
6431
6484
|
const { priceInputContainerRef, priceInputContainerWidth } = usePriceInputContainer({
|
|
6432
6485
|
order_type_ext: formattedOrder.order_type_ext
|
|
6433
6486
|
});
|
|
6487
|
+
const effectiveEstLiqPriceForSlCheck = React3.useMemo(() => {
|
|
6488
|
+
const estLiqPrice = state.estLiqPrice;
|
|
6489
|
+
if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
|
|
6490
|
+
return null;
|
|
6491
|
+
}
|
|
6492
|
+
if (formattedOrder.side === types.OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === types.OrderSide.SELL && estLiqPrice < state.markPrice) {
|
|
6493
|
+
return null;
|
|
6494
|
+
}
|
|
6495
|
+
if (!Number.isFinite(estLiqPrice) || estLiqPrice <= 0) {
|
|
6496
|
+
return null;
|
|
6497
|
+
}
|
|
6498
|
+
return estLiqPrice;
|
|
6499
|
+
}, [state.estLiqPrice, state.markPrice, formattedOrder.side]);
|
|
6434
6500
|
const slPriceError = hooks.useTpslPriceChecker({
|
|
6435
6501
|
slPrice: formattedOrder.sl_trigger_price,
|
|
6436
|
-
liqPrice:
|
|
6502
|
+
liqPrice: effectiveEstLiqPriceForSlCheck,
|
|
6437
6503
|
side: formattedOrder.side,
|
|
6504
|
+
markPrice: state.markPrice,
|
|
6438
6505
|
currentPosition: state.currentPosition,
|
|
6439
6506
|
orderQuantity: Number(formattedOrder.order_quantity)
|
|
6440
6507
|
});
|
|
@@ -6449,12 +6516,7 @@ var useOrderEntryScript = (inputs) => {
|
|
|
6449
6516
|
}
|
|
6450
6517
|
}, [tpslSwitch]);
|
|
6451
6518
|
React3.useEffect(() => {
|
|
6452
|
-
|
|
6453
|
-
if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
|
|
6454
|
-
estLiqPrice = null;
|
|
6455
|
-
} else if (formattedOrder.side === types.OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === types.OrderSide.SELL && estLiqPrice < state.markPrice) {
|
|
6456
|
-
estLiqPrice = null;
|
|
6457
|
-
}
|
|
6519
|
+
const estLiqPrice = effectiveEstLiqPriceForSlCheck;
|
|
6458
6520
|
const lastActive = lastUserActiveTimeRef.current;
|
|
6459
6521
|
const now = Date.now();
|
|
6460
6522
|
const isUserActive = now - lastActive <= ORDER_ENTRY_EST_LIQ_ACTIVE_WINDOW_MS;
|
|
@@ -6463,7 +6525,7 @@ var useOrderEntryScript = (inputs) => {
|
|
|
6463
6525
|
estLiqPrice,
|
|
6464
6526
|
isUserActive
|
|
6465
6527
|
});
|
|
6466
|
-
}, [ee, symbol,
|
|
6528
|
+
}, [ee, symbol, effectiveEstLiqPriceForSlCheck]);
|
|
6467
6529
|
React3.useEffect(() => {
|
|
6468
6530
|
setOrderValue("margin_mode", marginMode);
|
|
6469
6531
|
}, [marginMode]);
|