/** * @Author: ?? * @Date: ?? */ import React, { useCallback, useEffect, useImperativeHandle, useState } from "react"; import { AdjustingLeverModalProps, AdjustingLeverModalRefFuncProps, AdjustingLeverModalConfirmProps } from "./interface"; import { Modal, ModalProps, NumberInput, Slider } from "../../index"; import { Minus } from "@icons/Minus"; import { Plus } from "@icons/Plus"; import IconCom from "@icons/IconCom"; import { PosiRadio } from "@components/AdjustingLeverModal/PosiRadio"; import { createAveragePoints, createMarks, findNearestTarget, originalNodes } from "@components/AdjustingLeverModal/helpers"; import "./index.css"; import { invertObj } from "ramda"; import { MarginTypeEnum } from "@shared/types"; import { formatMoney, toDefaultNumber } from "@utils/FormatNumber"; /** * ### 引用方法 * ```tsx * import { AdjustingLeverModal } from "@atomintl/exchange-ui"; * ``` */ export const AdjustingLeverModal: React.FC = props => { const { onConfirm, defaultLever, defaultOriginalNodes, initMarginType, disabledCross, disabledIsolated, open, askLimits } = props; const marks: any = createMarks(defaultOriginalNodes || originalNodes); const averagePoints = createAveragePoints(marks); const invertAveragePoints = invertObj(averagePoints); const marksKeys = Object.keys(marks) .map(Number) .sort((a, b) => a - b); const minLever = marksKeys[0]; const maxLever = marksKeys[marksKeys.length - 1]; const [step, setStep] = useState(1); const [lever, setLever] = useState(defaultLever ? averagePoints[defaultLever] : 1); const [notionalCap, setNotionalCap] = useState(); const [marginType, setMarginType] = useState(initMarginType || MarginTypeEnum.Cross); const bulkingStep = (key: number) => { return (marksKeys[key + 1] - marksKeys[key]) / (marks[marksKeys[key + 1]].value - marks[marksKeys[key]].value); }; const calcStep = (_lever: number, dir: "dec" | "inc") => { const isDec = dir === "dec"; for (let k = 0; k < marksKeys.length - 2; k++) { ((_lever > marksKeys[k] && _lever < marksKeys[k + 1]) || (isDec && _lever === marksKeys[k + 1]) || (!isDec && _lever === marksKeys[k])) && setStep(bulkingStep(k)); } }; const decreaseLever = () => { const currentLeverKey = Number(invertAveragePoints[lever]); if (currentLeverKey <= minLever) return; calcStep(lever, "dec"); setLever(Number(averagePoints[currentLeverKey - 1])); }; const increaseLever = () => { const currentLeverKey = Number(invertAveragePoints[lever]); if (currentLeverKey >= maxLever) return; calcStep(lever, "inc"); setLever(Number(averagePoints[currentLeverKey + 1])); }; const onOkCb = useCallback(() => { onConfirm?.({ lever: Number(invertAveragePoints[Number(lever)] || 1), marginType, notionalCap }); }, [lever, marginType, notionalCap]); const tipFormatter = () => { return `${invertAveragePoints[Number(lever)] || 1}x`; }; const onSliderChange = (v: number | number[]) => { calcStep(Number(v), "dec"); const sortedAveragePointsKeys = Object.keys(invertAveragePoints) .map(Number) .sort((a, b) => a - b); const calibratedSliderValue = findNearestTarget(sortedAveragePointsKeys, Number(v)); setLever(calibratedSliderValue); }; const onValueUpdate = useCallback( (v: string | number) => { let _v = Number(v); // if (_v < minLever) _v = minLever if (_v > maxLever) _v = maxLever; setLever(averagePoints[_v]); }, [averagePoints] ); useImperativeHandle(props?.onRef, () => ({ onValueUpdate })); useEffect(() => { //set up initState if (open) { setStep(1); setLever(defaultLever ? averagePoints[defaultLever] : 1); setMarginType(initMarginType || MarginTypeEnum.Cross); } }, [open]); useEffect(() => { if (askLimits?.length) { const _initialLeverage = invertAveragePoints[lever]; const _askLimits = askLimits?.sort( (a: any, b: any) => toDefaultNumber(a?.initialLeverage) - toDefaultNumber(b?.initialLeverage) ); let _notionalCap = 0; for (let k = 0; k < _askLimits.length; k++) { _notionalCap = toDefaultNumber(_askLimits[k].notionalCap); if (toDefaultNumber(_initialLeverage) <= toDefaultNumber(_askLimits[k].initialLeverage)) { break; } } setNotionalCap(toDefaultNumber(_notionalCap)); } }, [lever, askLimits]); return ( <>
杠杆倍数
{`x`}} />
当前杠杆倍数最高可持有头寸:{formatMoney(toDefaultNumber(notionalCap))} USDT
{toDefaultNumber(invertAveragePoints[Number(lever)]) > 10 ? (
当前杠杆倍数较高,容易导致强平,请谨慎调整!
) : null}
); }; AdjustingLeverModal.defaultProps = {}; export type { AdjustingLeverModalProps, AdjustingLeverModalRefFuncProps, AdjustingLeverModalConfirmProps }; export default AdjustingLeverModal;