@orderly.network/ui-order-entry 2.8.5 → 2.8.6-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
@@ -1,9 +1,9 @@
1
1
  import React3, { useId, forwardRef, useState, useImperativeHandle, useEffect, memo, createContext, useMemo, useRef, useCallback, useContext } from 'react';
2
- import { useLocalStorage, utils, usePositionStream, useEventEmitter, useDebouncedCallback, useFeeState, useRwaSymbolsInfoStore, useOrderlyContext, useMemoizedFn, useOrderEntry, useMarginRatio, useComputedLTV, useHoldingStream, useAppStore, useIndexPricesStream, useTrack, useQuery, useSymbolLeverage, useBoolean } from '@orderly.network/hooks';
2
+ import { useLocalStorage, utils, usePositionStream, useEventEmitter, useDebouncedCallback, useFeeState, useRwaSymbolsInfoStore, useOrderlyContext, ERROR_MSG_CODES, useMemoizedFn, useOrderEntry, useMarginRatio, useComputedLTV, useTpslPriceChecker, useHoldingStream, useAppStore, useIndexPricesStream, useTrack, useQuery, useSymbolLeverage, useBoolean } from '@orderly.network/hooks';
3
3
  import { useTranslation, i18n } from '@orderly.network/i18n';
4
4
  import { useOrderEntryFormErrorMsg, useCanTrade } from '@orderly.network/react-app';
5
5
  import { EMPTY_LIST, DistributionType, TrailingCallbackType, OrderSide, OrderType, PositionType, BBOOrderType, OrderLevel, TrackerEventName } from '@orderly.network/types';
6
- import { ExclamationFillIcon, modal, Text, Tooltip, TooltipTrigger, Flex, Input, cn, inputFormatter, Box, registerSimpleDialog, SimpleDialog, Select, Grid, Checkbox, Slider, textVariants, SettingFillIcon, Badge, Divider, Button, TokenIcon, DataTable, SimpleDropdownMenu, CaretDownIcon, Switch, useScreen, toast, ThrottledButton, SimpleSheet, InfoCircleIcon, AddCircleIcon, PopoverRoot, PopoverTrigger, PopoverContent, EditIcon as EditIcon$1, useModal } from '@orderly.network/ui';
6
+ import { ExclamationFillIcon, modal, Text, Tooltip, TooltipTrigger, Flex, Input, cn, inputFormatter, Box, registerSimpleDialog, SimpleDialog, Select, Grid, Checkbox, Slider, textVariants, SettingFillIcon, Badge, Divider, Button, TokenIcon, DataTable, SimpleDropdownMenu, CaretDownIcon, Switch, useScreen, toast, ThrottledButton, SimpleSheet, InfoCircleIcon, AddCircleIcon, PopoverRoot, PopoverTrigger, PopoverContent, DotStatus, EditIcon as EditIcon$1, useModal } from '@orderly.network/ui';
7
7
  import { TPSLPositionTypeWidget, TPSLAdvancedWidget } from '@orderly.network/ui-tpsl';
8
8
  import { Decimal, zero, todpIfNeed, getBBOType, removeTrailingZeros } from '@orderly.network/utils';
9
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -1046,6 +1046,7 @@ var LTVRiskTooltipWidget = () => {
1046
1046
  var Available = (props) => {
1047
1047
  const { canTrade, currentLtv, quote, freeCollateral } = props;
1048
1048
  const { t } = useTranslation();
1049
+ const { isMobile } = useScreen();
1049
1050
  const showLTV = useMemo(() => {
1050
1051
  return typeof currentLtv === "number" && !Number.isNaN(currentLtv) && currentLtv > 0;
1051
1052
  }, [currentLtv]);
@@ -1085,7 +1086,8 @@ var Available = (props) => {
1085
1086
  color: "secondary",
1086
1087
  className: "oui-p-0 hover:oui-text-base-contrast-80",
1087
1088
  onClick: () => {
1088
- modal.show("DepositAndWithdrawWithDialogId", {
1089
+ const handleDomId = isMobile ? "DepositAndWithdrawWithSheetId" : "DepositAndWithdrawWithDialogId";
1090
+ modal.show(handleDomId, {
1089
1091
  activeTab: "deposit"
1090
1092
  });
1091
1093
  },
@@ -3769,8 +3771,10 @@ var OrderTPSL = (props) => {
3769
3771
  props.onSwitchChanged(false);
3770
3772
  }
3771
3773
  }, [props.orderType]);
3772
- if (props.orderType !== OrderType.LIMIT && props.orderType !== OrderType.MARKET || props.isReduceOnly)
3774
+ if (props.orderType !== OrderType.LIMIT && props.orderType !== OrderType.MARKET) {
3773
3775
  return null;
3776
+ }
3777
+ const isSlPriceWarning = props.errors?.["sl_trigger_price"]?.["type"] === ERROR_MSG_CODES.SL_PRICE_WARNING;
3774
3778
  return /* @__PURE__ */ jsxs("div", { children: [
3775
3779
  /* @__PURE__ */ jsxs(Flex, { itemAlign: "center", justify: "between", children: [
3776
3780
  /* @__PURE__ */ jsxs(Flex, { itemAlign: "center", gapX: 1, children: [
@@ -3780,7 +3784,7 @@ var OrderTPSL = (props) => {
3780
3784
  id: "order_entry_tpsl",
3781
3785
  className: "oui-h-[14px]",
3782
3786
  checked: props.switchState,
3783
- disabled: props.orderType !== OrderType.LIMIT && props.orderType !== OrderType.MARKET || props.isReduceOnly,
3787
+ disabled: props.orderType !== OrderType.LIMIT && props.orderType !== OrderType.MARKET,
3784
3788
  onCheckedChange: (checked) => {
3785
3789
  props.onSwitchChanged(checked);
3786
3790
  }
@@ -3828,16 +3832,29 @@ var OrderTPSL = (props) => {
3828
3832
  setOrderValue: props.setOrderValue,
3829
3833
  onChange: props.onChange,
3830
3834
  values: props.values,
3831
- errors: props.errors,
3835
+ errors: isSlPriceWarning ? {} : props.errors,
3832
3836
  quote_dp: props.quote_dp,
3833
3837
  showTPSLAdvanced: props.showTPSLAdvanced,
3834
- isMobile
3838
+ isMobile,
3839
+ isSlPriceWarning
3835
3840
  }
3836
3841
  )
3837
3842
  }
3838
- )
3843
+ ),
3844
+ isSlPriceWarning && /* @__PURE__ */ jsx(TPSLPriceWarning, { errors: props.errors })
3839
3845
  ] });
3840
3846
  };
3847
+ var TPSLPriceWarning = (props) => {
3848
+ const { getErrorMsg } = useOrderEntryFormErrorMsg(props.errors);
3849
+ return /* @__PURE__ */ jsx(
3850
+ DotStatus,
3851
+ {
3852
+ color: "warning",
3853
+ size: "xs",
3854
+ label: getErrorMsg("sl_trigger_price")
3855
+ }
3856
+ );
3857
+ };
3841
3858
  var TPSLInputForm = React3.forwardRef((props, ref) => {
3842
3859
  const { getErrorMsg } = useOrderEntryFormErrorMsg(props.errors);
3843
3860
  const { t } = useTranslation();
@@ -3890,6 +3907,9 @@ var TPSLInputForm = React3.forwardRef((props, ref) => {
3890
3907
  first: "oui-testid-orderEntry-tpsl-slPrice-input",
3891
3908
  second: "oui-testid-orderEntry-tpsl-slPnl-input",
3892
3909
  dropDown: "oui-testid-orderEntry-tpsl-sl-dropDown-trigger-button"
3910
+ },
3911
+ classNames: {
3912
+ root: props.isSlPriceWarning ? "oui-outline-warning-darken focus-within:oui-outline-warning-darken" : void 0
3893
3913
  }
3894
3914
  }
3895
3915
  ) })
@@ -4006,8 +4026,12 @@ var TPSLTriggerPriceInput = (props) => {
4006
4026
  value: innerValue,
4007
4027
  classNames: {
4008
4028
  additional: "oui-text-base-contrast-54",
4009
- root: "oui-pr-2 md:oui-pr-3",
4010
- prefix: "oui-pr-1 md:oui-pr-2"
4029
+ root: cn("oui-pr-2 md:oui-pr-3", props.classNames?.root),
4030
+ prefix: cn("oui-pr-1 md:oui-pr-2", props.classNames?.prefix),
4031
+ input: cn(
4032
+ "oui-text-2xs placeholder:oui-text-2xs",
4033
+ props.classNames?.input
4034
+ )
4011
4035
  },
4012
4036
  onValueChange,
4013
4037
  formatters: [
@@ -4027,6 +4051,7 @@ var TPSLInputRow = (props) => {
4027
4051
  type: props.type,
4028
4052
  error: props.error,
4029
4053
  values: props.values ?? "",
4054
+ classNames: props.classNames,
4030
4055
  onChange: (event) => {
4031
4056
  props.onChange(
4032
4057
  props.type === "SL" ? "sl_trigger_price" : "tp_trigger_price",
@@ -4103,6 +4128,7 @@ var OrderEntry = (props) => {
4103
4128
  });
4104
4129
  const { notification } = useOrderlyContext();
4105
4130
  const soundAlertId = useId();
4131
+ const isSlPriceWarning = props.slPriceError?.sl_trigger_price?.type === ERROR_MSG_CODES.SL_PRICE_WARNING;
4106
4132
  const { getErrorMsg } = useOrderEntryFormErrorMsg(validated ? errors : null);
4107
4133
  const buttonLabel = useMemo(() => {
4108
4134
  return side === OrderSide.BUY ? t("orderEntry.buyLong") : t("orderEntry.sellShort");
@@ -4146,7 +4172,8 @@ var OrderEntry = (props) => {
4146
4172
  }, [errorMsgVisible]);
4147
4173
  const onSubmit = useMemoizedFn(async () => {
4148
4174
  const isScaledOrder = formattedOrder.order_type === OrderType.SCALED;
4149
- helper.validate().then(
4175
+ const isSlPriceError = props.slPriceError?.sl_trigger_price?.type === ERROR_MSG_CODES.SL_PRICE_ERROR;
4176
+ helper.validate(isSlPriceError ? props.slPriceError : void 0).then(
4150
4177
  // validate success, it return the order
4151
4178
  // TODO: get order from other function
4152
4179
  (order) => {
@@ -4278,6 +4305,7 @@ var OrderEntry = (props) => {
4278
4305
  useEffect(() => {
4279
4306
  setHasAdvancedTPSLResult(false);
4280
4307
  }, [props.symbol]);
4308
+ const showReduceOnlySection = isMobile && formattedOrder.order_type !== OrderType.LIMIT && formattedOrder.order_type !== OrderType.MARKET || !isMobile;
4281
4309
  const showSoundSection = Boolean(notification?.orderFilled?.media) && (notification?.orderFilled?.displayInOrderEntry ?? true);
4282
4310
  const additionalInfoProps = {
4283
4311
  pinned,
@@ -4422,8 +4450,7 @@ var OrderEntry = (props) => {
4422
4450
  switchState: props.tpslSwitch,
4423
4451
  onSwitchChanged: props.setTpslSwitch,
4424
4452
  orderType: formattedOrder.order_type,
4425
- errors: validated ? errors : null,
4426
- isReduceOnly: formattedOrder.reduce_only,
4453
+ errors: validated || isSlPriceWarning ? { ...errors, ...props.slPriceError } : null,
4427
4454
  setOrderValue,
4428
4455
  reduceOnlyChecked: formattedOrder.reduce_only ?? false,
4429
4456
  onReduceOnlyChange: (checked) => {
@@ -4452,7 +4479,7 @@ var OrderEntry = (props) => {
4452
4479
  }
4453
4480
  }
4454
4481
  ),
4455
- (isMobile && (formattedOrder.order_type !== OrderType.LIMIT && formattedOrder.order_type !== OrderType.MARKET || formattedOrder.reduce_only) || !isMobile) && /* @__PURE__ */ jsxs(Flex, { justify: "between", itemAlign: "center", className: "oui-mt-2", children: [
4482
+ showReduceOnlySection && /* @__PURE__ */ jsxs(Flex, { justify: "between", itemAlign: "center", className: "oui-mt-2", children: [
4456
4483
  /* @__PURE__ */ jsx(
4457
4484
  ReduceOnlySwitch,
4458
4485
  {
@@ -4883,8 +4910,24 @@ var useOrderEntryScript = (inputs) => {
4883
4910
  const { priceInputContainerRef, priceInputContainerWidth } = usePriceInputContainer({
4884
4911
  order_type_ext: formattedOrder.order_type_ext
4885
4912
  });
4913
+ const slPriceError = useTpslPriceChecker({
4914
+ slPrice: formattedOrder.sl_trigger_price,
4915
+ liqPrice: state.estLiqPrice,
4916
+ side: formattedOrder.side
4917
+ });
4918
+ useEffect(() => {
4919
+ if (formattedOrder.reduce_only) {
4920
+ setTpslSwitch(false);
4921
+ }
4922
+ }, [formattedOrder.reduce_only]);
4923
+ useEffect(() => {
4924
+ if (tpslSwitch) {
4925
+ setOrderValue("reduce_only", false);
4926
+ }
4927
+ }, [tpslSwitch]);
4886
4928
  return {
4887
4929
  ...state,
4930
+ slPriceError: slPriceError ?? void 0,
4888
4931
  side: formattedOrder.side,
4889
4932
  type: formattedOrder.order_type,
4890
4933
  level: formattedOrder.level,