@rabbitio/ui-kit 1.0.0-beta.43 → 1.0.0-beta.46
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/coverage/clover.xml +5262 -821
- package/coverage/coverage-final.json +25 -1
- package/coverage/index.html +311 -26
- package/coverage/rabbit-ui-kit/index.html +1 -1
- package/coverage/rabbit-ui-kit/index.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/adapters/axiosAdapter.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/adapters/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/amountUtils.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/errorUtils.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/external-apis/apiGroups.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/external-apis/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/external-apis/ipAddressProviders.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/fiatCurrenciesService.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/models/blockchain.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/models/coin.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/models/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/models/protocol.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/cache.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/emailAPI.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/logging/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/logging/logger.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/logging/logsStorage.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/postponeExecution.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/common/utils/safeStringify.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/AssetIcon/AssetIcon.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/AssetIcon/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/AssetSelection/AssetSelection.jsx.html +364 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/AssetSelection/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +217 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/BackgroundTitle/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/LoadingDots/LoadingDots.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/LoadingDots/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/NoticeIcon/NoticeIcon.jsx.html +298 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/NoticeIcon/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/SupportChat/SupportChat.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/SupportChat/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/TitleBox/TitleBox.jsx.html +574 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/TitleBox/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/Tooltip/Tooltip.jsx.html +370 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/Tooltip/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/Validation/Validation.jsx.html +475 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/Validation/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Button/Button.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Button/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Close/Close.jsx.html +277 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Close/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/LinkButton/LinkButton.jsx.html +448 -0
- package/coverage/rabbit-ui-kit/src/components/atoms/buttons/LinkButton/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/hooks/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/hooks/useCallHandlingErrors.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/hooks/useReferredState.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/molecules/AmountInput/AmountInput.jsx.html +1510 -0
- package/coverage/rabbit-ui-kit/src/components/molecules/AmountInput/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/Dialog.jsx.html +1630 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +451 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/DialogButtons/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +2077 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/DialogStep/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/Dialog/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/SwapForm/SwapForm.jsx.html +3538 -0
- package/coverage/rabbit-ui-kit/src/components/organisms/SwapForm/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/components/utils/index.html +24 -9
- package/coverage/rabbit-ui-kit/src/components/utils/inputValueProviders.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/utils/textUtils.js.html +139 -0
- package/coverage/rabbit-ui-kit/src/components/utils/uiUtils.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/components/utils/urlQueryUtils.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/constants/organisms/dialog/DialogStep/dialogStep.js.html +88 -0
- package/coverage/rabbit-ui-kit/src/constants/organisms/dialog/DialogStep/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/constants/organisms/dialog/dialog.js.html +172 -0
- package/coverage/rabbit-ui-kit/src/constants/organisms/dialog/index.html +116 -0
- package/coverage/rabbit-ui-kit/src/index.html +5 -5
- package/coverage/rabbit-ui-kit/src/index.js.html +65 -5
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cacheAndConcurrentRequestsResolver.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cachedRobustExternalApiCallerService.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cancelProcessing.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/concurrentCalculationsMetadataHolder.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/externalApiProvider.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/externalServicesStatsCollector.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/robustExternalAPICallerService.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwap.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/models/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/services/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/services/publicSwapService.js.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/utils/index.html +1 -1
- package/coverage/rabbit-ui-kit/src/swaps-lib/utils/swapUtils.js.html +1 -1
- package/coverage/rabbit-ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +202 -0
- package/coverage/rabbit-ui-kit/stories/atoms/LoadingDots.stories.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/stories/atoms/Validation.stories.jsx.html +178 -0
- package/coverage/rabbit-ui-kit/stories/atoms/buttons/Button.stories.jsx.html +1 -1
- package/coverage/rabbit-ui-kit/stories/atoms/buttons/Close.stories.jsx.html +211 -0
- package/coverage/rabbit-ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +298 -0
- package/coverage/rabbit-ui-kit/stories/atoms/buttons/index.html +35 -5
- package/coverage/rabbit-ui-kit/stories/atoms/index.html +35 -5
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +574 -0
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +328 -0
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/index.html +116 -0
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +352 -0
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/index.html +116 -0
- package/coverage/rabbit-ui-kit/stories/organisms/Dialog/index.html +116 -0
- package/coverage/rabbit-ui-kit/stories/stubs/exampleContent.jsx.html +145 -0
- package/coverage/rabbit-ui-kit/stories/stubs/index.html +116 -0
- package/dist/index.cjs +3022 -231
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +40976 -0
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +2568 -183
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +3010 -239
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +3019 -234
- package/dist/index.umd.js.map +1 -1
- package/package.json +7 -1
- package/src/assets/image/icons/arrow-darker.svg +14 -0
- package/src/assets/image/icons/arrow-tosca.svg +3 -0
- package/src/assets/image/icons/arrow-white.svg +14 -0
- package/src/assets/image/icons/dark-rectangle.svg +3 -0
- package/src/assets/image/icons/failed-validation-icon.svg +15 -0
- package/src/assets/image/icons/successful-validation-icon.svg +10 -0
- package/src/assets/image/icons/wallet-gray-small.svg +6 -0
- package/src/components/atoms/AssetSelection/AssetSelection.jsx +93 -0
- package/src/components/atoms/AssetSelection/asset-selection.module.scss +55 -0
- package/src/components/atoms/BackgroundTitle/BackgroundTitle.jsx +44 -0
- package/src/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
- package/src/components/atoms/NoticeIcon/NoticeIcon.jsx +71 -0
- package/src/components/atoms/NoticeIcon/notice-icon.module.scss +14 -0
- package/src/components/atoms/TitleBox/TitleBox.jsx +163 -0
- package/src/components/atoms/TitleBox/title-box.module.scss +30 -0
- package/src/components/atoms/Tooltip/Tooltip.jsx +95 -0
- package/src/components/atoms/Tooltip/tooltip.module.scss +231 -0
- package/src/components/atoms/Validation/Validation.jsx +130 -0
- package/src/components/atoms/Validation/validation.module.scss +15 -0
- package/src/components/atoms/buttons/Close/Close.jsx +64 -0
- package/src/components/atoms/buttons/Close/close.module.scss +75 -0
- package/src/components/atoms/buttons/LinkButton/LinkButton.jsx +121 -0
- package/src/components/atoms/buttons/LinkButton/link-button.module.scss +45 -0
- package/src/components/molecules/AmountInput/AmountInput.jsx +475 -0
- package/src/components/molecules/AmountInput/amount-input.module.scss +189 -0
- package/src/components/organisms/Dialog/Dialog.jsx +515 -0
- package/src/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +122 -0
- package/src/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
- package/src/components/organisms/Dialog/DialogStep/DialogStep.jsx +664 -0
- package/src/components/organisms/Dialog/DialogStep/dialog-step.module.scss +362 -0
- package/src/components/organisms/Dialog/dialog.module.scss +223 -0
- package/src/components/organisms/SwapForm/SwapForm.jsx +1151 -0
- package/src/components/organisms/SwapForm/swap-form.module.scss +120 -0
- package/src/components/utils/textUtils.js +18 -0
- package/src/constants/organisms/dialog/DialogStep/dialogStep.js +1 -0
- package/src/constants/organisms/dialog/dialog.js +29 -0
- package/src/index.js +21 -1
- package/stories/stubs/exampleContent.jsx +20 -0
- package/styles/fonts/NunitoSans-Bold.ttf +0 -0
- package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
- package/styles/fonts/NunitoSans-Light.ttf +0 -0
- package/styles/fonts/NunitoSans-Regular.ttf +0 -0
- package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
- package/styles/index.scss +5 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import { useCallHandlingErrors } from "../../../hooks/useCallHandlingErrors";
|
|
5
|
+
|
|
6
|
+
import s from "./link-button.module.scss";
|
|
7
|
+
import { LoadingDots } from "../../LoadingDots/LoadingDots";
|
|
8
|
+
|
|
9
|
+
export const iconRotateOptions = {
|
|
10
|
+
rotate0: "0deg",
|
|
11
|
+
rotate90: "90deg",
|
|
12
|
+
rotate180: "180deg",
|
|
13
|
+
rotate270: "270deg",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* LinkButton renders a clickable button which can optionally display an icon and loading animation.
|
|
18
|
+
* It can also be styled to be colored or disabled. This button supports rotating the icon according to specified degrees.
|
|
19
|
+
*
|
|
20
|
+
* @component
|
|
21
|
+
* @param {Object} props - Properties passed down to the component.
|
|
22
|
+
* @param {Function} props.onClick - Callback function triggered on button click. It should handle any post-click logic like resetting loading state.
|
|
23
|
+
* @param {boolean} props.isDisabled - If true, the button will be disabled and non-interactable.
|
|
24
|
+
* @param {boolean} props.isLoadable - If true, the button will display a loading indicator upon being clicked.
|
|
25
|
+
* @param {string} props.content - Text content displayed on the button.
|
|
26
|
+
* @param {boolean} props.isColored - If true, applies additional styling to the button.
|
|
27
|
+
* @param {string} props.icon - URL of an icon image to be displayed on the button.
|
|
28
|
+
* @param {string} props.iconRotate - Rotation angle for the icon. Valid values are defined in `iconRotateOptions`.
|
|
29
|
+
* @param {Object} props.IconComponent - Icon component, if SVG is imported directly.
|
|
30
|
+
*
|
|
31
|
+
* @returns {JSX.Element} A React component that renders a clickable and optionally loadable and icon-displaying button.
|
|
32
|
+
*/
|
|
33
|
+
export const LinkButton = ({
|
|
34
|
+
onClick = (resetButtonLoader) => {},
|
|
35
|
+
isDisabled = false,
|
|
36
|
+
isLoadable = false,
|
|
37
|
+
content = "",
|
|
38
|
+
isColored = true,
|
|
39
|
+
icon,
|
|
40
|
+
iconRotate,
|
|
41
|
+
IconComponent,
|
|
42
|
+
}) => {
|
|
43
|
+
const callHandlingErrors = useCallHandlingErrors();
|
|
44
|
+
|
|
45
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
46
|
+
const [processedIconRotation, setProcessedIconRotation] = useState(null);
|
|
47
|
+
|
|
48
|
+
const handleClick = () => {
|
|
49
|
+
callHandlingErrors(() => {
|
|
50
|
+
if (!isDisabled) {
|
|
51
|
+
if (isLoadable) {
|
|
52
|
+
setIsLoading(true);
|
|
53
|
+
}
|
|
54
|
+
// TODO: [bug, moderate] Click can be called when there isLoading=true task_id=a15979a4ca2042b29dfd1d128a16c281
|
|
55
|
+
onClick(() => setIsLoading(false));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (
|
|
62
|
+
iconRotate &&
|
|
63
|
+
Object.keys(iconRotateOptions).find(
|
|
64
|
+
(key) => iconRotateOptions[key] === iconRotate
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
setProcessedIconRotation(iconRotate);
|
|
68
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
|
+
}, [iconRotate]);
|
|
70
|
+
|
|
71
|
+
return isLoading ? (
|
|
72
|
+
<LoadingDots isColored={true} />
|
|
73
|
+
) : (
|
|
74
|
+
<div
|
|
75
|
+
className={
|
|
76
|
+
s["link-button"] +
|
|
77
|
+
` ${
|
|
78
|
+
processedIconRotation &&
|
|
79
|
+
processedIconRotation !== iconRotateOptions.rotate0
|
|
80
|
+
? " " + s["icon-rotate-" + processedIconRotation]
|
|
81
|
+
: ""
|
|
82
|
+
} ${isDisabled ? " " + s["disabled"] : ""}`
|
|
83
|
+
}
|
|
84
|
+
onClick={handleClick}
|
|
85
|
+
>
|
|
86
|
+
{icon ? <img src={icon} alt="link button alt" /> : null}
|
|
87
|
+
{IconComponent ? <IconComponent /> : null}
|
|
88
|
+
<p
|
|
89
|
+
className={
|
|
90
|
+
s["link-button-text"] +
|
|
91
|
+
` ${isColored ? s["colored"] : ""} ${
|
|
92
|
+
isDisabled ? s["disabled"] : ""
|
|
93
|
+
}`
|
|
94
|
+
}
|
|
95
|
+
>
|
|
96
|
+
{content}
|
|
97
|
+
</p>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
LinkButton.propTypes = {
|
|
103
|
+
onClick: PropTypes.func,
|
|
104
|
+
isDisabled: PropTypes.bool,
|
|
105
|
+
isLoadable: PropTypes.bool,
|
|
106
|
+
content: PropTypes.string,
|
|
107
|
+
icon: PropTypes.string,
|
|
108
|
+
isColored: PropTypes.bool,
|
|
109
|
+
iconRotate: PropTypes.oneOf(Object.values(iconRotateOptions)),
|
|
110
|
+
IconComponent: PropTypes.elementType,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
LinkButton.defaultProps = {
|
|
114
|
+
onClick: (resetButtonLoader) => {},
|
|
115
|
+
isDisabled: false,
|
|
116
|
+
isLoadable: false,
|
|
117
|
+
content: "",
|
|
118
|
+
icon: undefined,
|
|
119
|
+
isColored: true,
|
|
120
|
+
iconRotate: iconRotateOptions.rotate0,
|
|
121
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@import "../../../../../styles/index";
|
|
2
|
+
|
|
3
|
+
.link-button {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
|
|
7
|
+
&:not(.disabled) {
|
|
8
|
+
@extend %hover-state;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
&.icon-rotate-90deg img {
|
|
12
|
+
transform: rotate(90deg);
|
|
13
|
+
}
|
|
14
|
+
&.icon-rotate-180deg img {
|
|
15
|
+
transform: rotate(180deg);
|
|
16
|
+
}
|
|
17
|
+
&.icon-rotate-270deg img {
|
|
18
|
+
transform: rotate(270deg);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
img {
|
|
22
|
+
margin-left: -3px;
|
|
23
|
+
margin-right: Margin("1");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&-text {
|
|
27
|
+
@extend %text-bold;
|
|
28
|
+
font-size: 14px;
|
|
29
|
+
color: $white;
|
|
30
|
+
text-decoration: none;
|
|
31
|
+
text-align: center;
|
|
32
|
+
line-height: 14px;
|
|
33
|
+
// padding-bottom: 1px;
|
|
34
|
+
margin: 0;
|
|
35
|
+
|
|
36
|
+
&.colored {
|
|
37
|
+
color: SolidColor("tosca");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&.disabled {
|
|
41
|
+
color: SolidColor("grey");
|
|
42
|
+
cursor: default;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { BigNumber } from "bignumber.js";
|
|
3
|
+
|
|
4
|
+
import s from "./amount-input.module.scss";
|
|
5
|
+
// import { ReactComponent as WalletIcon } from "../../../assets/image/icons/wallet-gray-small.svg";
|
|
6
|
+
|
|
7
|
+
import { useCallHandlingErrors } from "../../hooks/useCallHandlingErrors.js";
|
|
8
|
+
import { InputValuesProviders } from "../../utils/inputValueProviders.js";
|
|
9
|
+
import { logErrorOrOutputToConsole } from "../../../common/errorUtils.js";
|
|
10
|
+
|
|
11
|
+
import { TitleBox } from "../../atoms/TitleBox/TitleBox.jsx";
|
|
12
|
+
import { AmountUtils } from "../../../common/amountUtils.js";
|
|
13
|
+
import { LoadingDots } from "../../atoms/LoadingDots/LoadingDots.jsx";
|
|
14
|
+
import { AssetSelection } from "../../atoms/AssetSelection/AssetSelection.jsx";
|
|
15
|
+
import { Validation } from "../../atoms/Validation/Validation.jsx";
|
|
16
|
+
|
|
17
|
+
const WalletIcon = () => (
|
|
18
|
+
<svg
|
|
19
|
+
width="16"
|
|
20
|
+
height="16"
|
|
21
|
+
viewBox="0 0 16 16"
|
|
22
|
+
fill="none"
|
|
23
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
24
|
+
>
|
|
25
|
+
<path
|
|
26
|
+
d="M12.6265 10.4119V12.2379C12.6265 12.7338 12.193 13.1356 11.6583 13.1356H3.26825C2.73352 13.1356 2.29999 12.7338 2.29999 12.2379V3.79771C2.29999 3.30178 2.73352 2.89999 3.26825 2.89999H11.6583C12.193 2.89999 12.6265 3.30178 12.6265 3.79771V5.84996"
|
|
27
|
+
stroke="#8F95A2"
|
|
28
|
+
stroke-linecap="round"
|
|
29
|
+
stroke-linejoin="round"
|
|
30
|
+
/>
|
|
31
|
+
<path
|
|
32
|
+
fill-rule="evenodd"
|
|
33
|
+
clip-rule="evenodd"
|
|
34
|
+
d="M13.0952 10.1922H10.2664C9.0847 10.1922 8.12704 9.23439 8.12704 8.05246C8.12704 6.87052 9.0847 5.91269 10.2664 5.91269H13.0952C13.4072 5.91269 13.66 6.16552 13.66 6.47758V9.62689C13.66 9.93939 13.4072 10.1922 13.0952 10.1922Z"
|
|
35
|
+
stroke="#8F95A2"
|
|
36
|
+
stroke-linecap="round"
|
|
37
|
+
stroke-linejoin="round"
|
|
38
|
+
/>
|
|
39
|
+
<path
|
|
40
|
+
d="M2.29999 4.73721H4.99884"
|
|
41
|
+
stroke="#8F95A2"
|
|
42
|
+
stroke-linecap="round"
|
|
43
|
+
stroke-linejoin="round"
|
|
44
|
+
/>
|
|
45
|
+
<path
|
|
46
|
+
d="M2.29999 11.3122H4.99884"
|
|
47
|
+
stroke="#8F95A2"
|
|
48
|
+
stroke-linecap="round"
|
|
49
|
+
stroke-linejoin="round"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
export const AmountInput = React.forwardRef(
|
|
55
|
+
(
|
|
56
|
+
{
|
|
57
|
+
label = "",
|
|
58
|
+
handleCoinAmountChange = (btcAmount) => {},
|
|
59
|
+
handleFiatAmountChange = (fiatAmount) => {},
|
|
60
|
+
handleChangeAssetClick = () => {},
|
|
61
|
+
handleBalanceValidationChange = (isValid) => {},
|
|
62
|
+
disabled,
|
|
63
|
+
alertText,
|
|
64
|
+
predefinedValue,
|
|
65
|
+
children,
|
|
66
|
+
ticker,
|
|
67
|
+
tickerPrintable,
|
|
68
|
+
assetDecimalPlaces,
|
|
69
|
+
assetBalance = { fiatAmount: null, assetAmount: null },
|
|
70
|
+
assetIconSrc,
|
|
71
|
+
assetIconProtocolSrc,
|
|
72
|
+
fallbackAssetIconSrc,
|
|
73
|
+
isSendAll = null,
|
|
74
|
+
handleSendAllClick = () => {},
|
|
75
|
+
showBalance = false,
|
|
76
|
+
showBalanceValidation = false,
|
|
77
|
+
showChangeAssetButton = false,
|
|
78
|
+
changeAssetButtonProtocol,
|
|
79
|
+
changeAssetButtonDisabled = false,
|
|
80
|
+
upperFormPosition,
|
|
81
|
+
lowerFormPosition,
|
|
82
|
+
errorEncountered,
|
|
83
|
+
updateAssetInputTo = null,
|
|
84
|
+
estimateAmount = false,
|
|
85
|
+
isLoading = false,
|
|
86
|
+
cryptoAssetToFiatRate = null,
|
|
87
|
+
fiatCurrencyCode = null,
|
|
88
|
+
fiatCurrencyDecimals = null,
|
|
89
|
+
linkButtonActiveText = null,
|
|
90
|
+
linkButtonInactiveText = null,
|
|
91
|
+
balanceLoaderText = null,
|
|
92
|
+
fiatInputPlaceholderText = null,
|
|
93
|
+
},
|
|
94
|
+
buttonForwardRef
|
|
95
|
+
) => {
|
|
96
|
+
// const { t } = useTranslation();
|
|
97
|
+
const callHandlingErrors = useCallHandlingErrors();
|
|
98
|
+
|
|
99
|
+
const [coinAmountValue, setCoinAmountValue] = useState("");
|
|
100
|
+
const [coinAmountPlaceholder, setCoinAmountPlaceholder] = useState("0");
|
|
101
|
+
const [fiatAmountValue, setFiatAmountValue] = useState("");
|
|
102
|
+
const [interactedWith, setInteractedWith] = useState(false);
|
|
103
|
+
const [fiatAmountAutoFocus, setFiatAmountAutoFocus] = useState(false);
|
|
104
|
+
const [isInFocus, setIsInFocus] = useState(false);
|
|
105
|
+
const [highlightBalance, setHighlightBalance] = useState(false);
|
|
106
|
+
const [highlightInput, setHighlightInput] = useState(false);
|
|
107
|
+
|
|
108
|
+
const resetToDefault = () => {
|
|
109
|
+
setInteractedWith(false);
|
|
110
|
+
setFiatAmountAutoFocus(false);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (updateAssetInputTo !== null)
|
|
115
|
+
handleChangeAmount(updateAssetInputTo?.toString(), false);
|
|
116
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
117
|
+
}, [updateAssetInputTo]);
|
|
118
|
+
|
|
119
|
+
const handleChangeAmount = (newAmountString, handlerEnabled = true) => {
|
|
120
|
+
(async () => {
|
|
121
|
+
try {
|
|
122
|
+
const correctedAmount =
|
|
123
|
+
InputValuesProviders.provideFormatOfFloatValueByInputString(
|
|
124
|
+
newAmountString,
|
|
125
|
+
assetDecimalPlaces
|
|
126
|
+
);
|
|
127
|
+
setCoinAmountValue(correctedAmount);
|
|
128
|
+
if (handlerEnabled) handleCoinAmountChange(correctedAmount);
|
|
129
|
+
|
|
130
|
+
if (
|
|
131
|
+
correctedAmount !== "" &&
|
|
132
|
+
cryptoAssetToFiatRate != null
|
|
133
|
+
) {
|
|
134
|
+
const fiatAmount = BigNumber(correctedAmount)
|
|
135
|
+
.times(cryptoAssetToFiatRate)
|
|
136
|
+
.toFixed(fiatCurrencyDecimals);
|
|
137
|
+
setFiatAmountValue(fiatAmount);
|
|
138
|
+
handleFiatAmountChange(fiatAmount);
|
|
139
|
+
} else {
|
|
140
|
+
setFiatAmountValue("");
|
|
141
|
+
}
|
|
142
|
+
} catch (e) {
|
|
143
|
+
setFiatAmountValue(null);
|
|
144
|
+
logErrorOrOutputToConsole(e);
|
|
145
|
+
}
|
|
146
|
+
})();
|
|
147
|
+
setInteractedWith(true);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleChangeAmountFiat = (newAmountString) => {
|
|
151
|
+
if (cryptoAssetToFiatRate == null) return;
|
|
152
|
+
(async () => {
|
|
153
|
+
try {
|
|
154
|
+
const correctedFiatAmount =
|
|
155
|
+
InputValuesProviders.provideFormatOfFloatValueByInputString(
|
|
156
|
+
newAmountString,
|
|
157
|
+
fiatCurrencyDecimals
|
|
158
|
+
);
|
|
159
|
+
setFiatAmountValue(correctedFiatAmount);
|
|
160
|
+
handleFiatAmountChange(correctedFiatAmount);
|
|
161
|
+
|
|
162
|
+
const coinAmount =
|
|
163
|
+
correctedFiatAmount !== ""
|
|
164
|
+
? BigNumber(correctedFiatAmount)
|
|
165
|
+
.div(cryptoAssetToFiatRate)
|
|
166
|
+
.toFixed(assetDecimalPlaces)
|
|
167
|
+
: "0";
|
|
168
|
+
const coinsAmount = BigNumber(coinAmount).isZero()
|
|
169
|
+
? ""
|
|
170
|
+
: coinAmount;
|
|
171
|
+
setCoinAmountValue(coinsAmount);
|
|
172
|
+
handleCoinAmountChange(coinsAmount);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
setFiatAmountValue(null);
|
|
175
|
+
logErrorOrOutputToConsole(e);
|
|
176
|
+
}
|
|
177
|
+
})();
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const placeholderByDecimalCount = (decimalCount) =>
|
|
181
|
+
"0" + (decimalCount > 0 ? "." + "0".repeat(decimalCount) : "");
|
|
182
|
+
|
|
183
|
+
const handleFiatInteraction = () => {
|
|
184
|
+
if (disabled) return;
|
|
185
|
+
setFiatAmountAutoFocus(true);
|
|
186
|
+
setInteractedWith(true);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
predefinedValue != null && handleChangeAmount(predefinedValue + "");
|
|
191
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
192
|
+
}, [predefinedValue]);
|
|
193
|
+
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
try {
|
|
196
|
+
setCoinAmountPlaceholder(
|
|
197
|
+
placeholderByDecimalCount(assetDecimalPlaces)
|
|
198
|
+
);
|
|
199
|
+
} catch (e) {
|
|
200
|
+
logErrorOrOutputToConsole(e);
|
|
201
|
+
}
|
|
202
|
+
resetToDefault();
|
|
203
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
204
|
+
}, [ticker]);
|
|
205
|
+
|
|
206
|
+
// Check if input & balance highlights are needed after a change in either the asset amount or the balance
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
if (!showBalanceValidation || assetBalance?.assetAmount == null)
|
|
209
|
+
return;
|
|
210
|
+
|
|
211
|
+
let enableHighlight = BigNumber(coinAmountValue).gt(
|
|
212
|
+
assetBalance?.assetAmount
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
handleBalanceValidationChange(enableHighlight);
|
|
216
|
+
setHighlightBalance(enableHighlight);
|
|
217
|
+
setHighlightInput(enableHighlight);
|
|
218
|
+
|
|
219
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
220
|
+
}, [coinAmountValue, assetBalance]);
|
|
221
|
+
|
|
222
|
+
// Clearing the custom focus upon disabling or enabling the form
|
|
223
|
+
useEffect(() => setIsInFocus(false), [disabled]);
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<>
|
|
227
|
+
<TitleBox
|
|
228
|
+
title={label}
|
|
229
|
+
linkText={
|
|
230
|
+
isSendAll !== null
|
|
231
|
+
? isSendAll
|
|
232
|
+
? linkButtonActiveText
|
|
233
|
+
: linkButtonInactiveText
|
|
234
|
+
: // ? t("molecules.AmountInput.send-all-enabled")
|
|
235
|
+
// : t("molecules.AmountInput.send-all-disabled")
|
|
236
|
+
null
|
|
237
|
+
}
|
|
238
|
+
linkButtonClick={handleSendAllClick}
|
|
239
|
+
>
|
|
240
|
+
<div
|
|
241
|
+
className={[
|
|
242
|
+
s["amount-input-container"],
|
|
243
|
+
isInFocus ? s["focus"] : "",
|
|
244
|
+
errorEncountered || highlightInput
|
|
245
|
+
? s["error-encountered"]
|
|
246
|
+
: "",
|
|
247
|
+
upperFormPosition ? s["upper-form-position"] : "",
|
|
248
|
+
lowerFormPosition ? s["lower-form-position"] : "",
|
|
249
|
+
].join(" ")}
|
|
250
|
+
>
|
|
251
|
+
<div
|
|
252
|
+
className={`${
|
|
253
|
+
s["amount-input-container-input-wrapper"]
|
|
254
|
+
} ${disabled ? s["disabled"] : ""}
|
|
255
|
+
${children ? s["bottom-margin"] : ""}`}
|
|
256
|
+
>
|
|
257
|
+
{showBalance ? (
|
|
258
|
+
<div
|
|
259
|
+
className={
|
|
260
|
+
s["asset-balance"] +
|
|
261
|
+
" " +
|
|
262
|
+
(highlightBalance ? s["red"] : "")
|
|
263
|
+
}
|
|
264
|
+
>
|
|
265
|
+
<WalletIcon />
|
|
266
|
+
<p>
|
|
267
|
+
{assetBalance?.assetAmount != null &&
|
|
268
|
+
assetBalance?.fiatAmount != null &&
|
|
269
|
+
ticker &&
|
|
270
|
+
fiatCurrencyCode ? (
|
|
271
|
+
<>
|
|
272
|
+
{AmountUtils.cryptoFull(
|
|
273
|
+
assetBalance.assetAmount,
|
|
274
|
+
tickerPrintable,
|
|
275
|
+
assetDecimalPlaces
|
|
276
|
+
)}
|
|
277
|
+
<span>
|
|
278
|
+
{" ~ " +
|
|
279
|
+
AmountUtils.fiat(
|
|
280
|
+
assetBalance.fiatAmount,
|
|
281
|
+
fiatCurrencyCode
|
|
282
|
+
)}
|
|
283
|
+
</span>
|
|
284
|
+
</>
|
|
285
|
+
) : (
|
|
286
|
+
balanceLoaderText
|
|
287
|
+
)}
|
|
288
|
+
</p>
|
|
289
|
+
</div>
|
|
290
|
+
) : (
|
|
291
|
+
""
|
|
292
|
+
)}
|
|
293
|
+
|
|
294
|
+
<div className={s["requested-amount-coin"]}>
|
|
295
|
+
<span
|
|
296
|
+
className={
|
|
297
|
+
s["requested-amount-coin-currency"]
|
|
298
|
+
}
|
|
299
|
+
>
|
|
300
|
+
{tickerPrintable
|
|
301
|
+
? (estimateAmount ? "~ " : "") +
|
|
302
|
+
tickerPrintable
|
|
303
|
+
: ""}
|
|
304
|
+
</span>
|
|
305
|
+
{!isLoading ? (
|
|
306
|
+
<input
|
|
307
|
+
type="text"
|
|
308
|
+
inputMode="decimal"
|
|
309
|
+
value={coinAmountValue}
|
|
310
|
+
onChange={(e) =>
|
|
311
|
+
handleChangeAmount(e.target.value)
|
|
312
|
+
}
|
|
313
|
+
placeholder={coinAmountPlaceholder}
|
|
314
|
+
className={
|
|
315
|
+
s["requested-amount-coin-input"]
|
|
316
|
+
}
|
|
317
|
+
disabled={disabled}
|
|
318
|
+
onFocus={(e) =>
|
|
319
|
+
callHandlingErrors(
|
|
320
|
+
() => setIsInFocus(true),
|
|
321
|
+
e
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
onBlur={(e) =>
|
|
325
|
+
callHandlingErrors(
|
|
326
|
+
() => setIsInFocus(false),
|
|
327
|
+
e
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
/>
|
|
331
|
+
) : (
|
|
332
|
+
<div
|
|
333
|
+
className={
|
|
334
|
+
s["requested-amount-coin-skeleton"]
|
|
335
|
+
}
|
|
336
|
+
>
|
|
337
|
+
<span
|
|
338
|
+
className={
|
|
339
|
+
s[
|
|
340
|
+
"requested-amount-coin-skeleton-content"
|
|
341
|
+
] +
|
|
342
|
+
" " +
|
|
343
|
+
s["skeleton-dark"]
|
|
344
|
+
}
|
|
345
|
+
></span>
|
|
346
|
+
</div>
|
|
347
|
+
)}
|
|
348
|
+
</div>
|
|
349
|
+
{fiatCurrencyCode !== null ? (
|
|
350
|
+
<>
|
|
351
|
+
<div
|
|
352
|
+
className={
|
|
353
|
+
s["requested-amount-fiat"] +
|
|
354
|
+
(interactedWith
|
|
355
|
+
? " " + s["interacted"]
|
|
356
|
+
: "")
|
|
357
|
+
}
|
|
358
|
+
>
|
|
359
|
+
{interactedWith ? (
|
|
360
|
+
<>
|
|
361
|
+
<span
|
|
362
|
+
className={
|
|
363
|
+
s[
|
|
364
|
+
"requested-amount-fiat-currency"
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
>
|
|
368
|
+
{(estimateAmount
|
|
369
|
+
? "~ "
|
|
370
|
+
: "") +
|
|
371
|
+
fiatCurrencyCode}
|
|
372
|
+
</span>
|
|
373
|
+
<input
|
|
374
|
+
type="text"
|
|
375
|
+
inputMode="decimal"
|
|
376
|
+
className={
|
|
377
|
+
s[
|
|
378
|
+
"requested-amount-fiat-input"
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
value={fiatAmountValue}
|
|
382
|
+
disabled={disabled}
|
|
383
|
+
onChange={(e) =>
|
|
384
|
+
handleChangeAmountFiat(
|
|
385
|
+
e.target.value
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
placeholder={placeholderByDecimalCount(
|
|
389
|
+
fiatCurrencyDecimals
|
|
390
|
+
)}
|
|
391
|
+
autoFocus={
|
|
392
|
+
fiatAmountAutoFocus
|
|
393
|
+
}
|
|
394
|
+
onFocus={(e) =>
|
|
395
|
+
callHandlingErrors(
|
|
396
|
+
() =>
|
|
397
|
+
setIsInFocus(
|
|
398
|
+
true
|
|
399
|
+
),
|
|
400
|
+
e
|
|
401
|
+
)
|
|
402
|
+
}
|
|
403
|
+
onBlur={(e) =>
|
|
404
|
+
callHandlingErrors(
|
|
405
|
+
() =>
|
|
406
|
+
setIsInFocus(
|
|
407
|
+
false
|
|
408
|
+
),
|
|
409
|
+
e
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
/>
|
|
413
|
+
</>
|
|
414
|
+
) : (
|
|
415
|
+
<span
|
|
416
|
+
className={
|
|
417
|
+
s[
|
|
418
|
+
"requested-amount-fiat-placeholder"
|
|
419
|
+
]
|
|
420
|
+
}
|
|
421
|
+
onClick={(e) =>
|
|
422
|
+
callHandlingErrors(
|
|
423
|
+
() =>
|
|
424
|
+
handleFiatInteraction(),
|
|
425
|
+
e
|
|
426
|
+
)
|
|
427
|
+
}
|
|
428
|
+
>
|
|
429
|
+
{fiatInputPlaceholderText}
|
|
430
|
+
{/*{t(*/}
|
|
431
|
+
{/* "molecules.AmountInput.fiat-placeholder-text",*/}
|
|
432
|
+
{/* {*/}
|
|
433
|
+
{/* currencyCode:*/}
|
|
434
|
+
{/* fiatCurrencyCode,*/}
|
|
435
|
+
{/* }*/}
|
|
436
|
+
{/*)}*/}
|
|
437
|
+
</span>
|
|
438
|
+
)}
|
|
439
|
+
</div>
|
|
440
|
+
</>
|
|
441
|
+
) : (
|
|
442
|
+
<LoadingDots
|
|
443
|
+
isColored={true}
|
|
444
|
+
noMargins={false}
|
|
445
|
+
align="left"
|
|
446
|
+
/>
|
|
447
|
+
)}
|
|
448
|
+
</div>
|
|
449
|
+
{showChangeAssetButton && ticker ? (
|
|
450
|
+
<div
|
|
451
|
+
className={
|
|
452
|
+
s["amount-input-container-button-wrapper"]
|
|
453
|
+
}
|
|
454
|
+
ref={buttonForwardRef}
|
|
455
|
+
>
|
|
456
|
+
<AssetSelection
|
|
457
|
+
assetIconSrc={assetIconSrc}
|
|
458
|
+
assetIconProtocolSrc={assetIconProtocolSrc}
|
|
459
|
+
fallbackSrc={fallbackAssetIconSrc}
|
|
460
|
+
handleClick={handleChangeAssetClick}
|
|
461
|
+
disabled={changeAssetButtonDisabled}
|
|
462
|
+
protocolName={changeAssetButtonProtocol}
|
|
463
|
+
/>
|
|
464
|
+
</div>
|
|
465
|
+
) : (
|
|
466
|
+
""
|
|
467
|
+
)}
|
|
468
|
+
{children}
|
|
469
|
+
</div>
|
|
470
|
+
</TitleBox>
|
|
471
|
+
{alertText ? <Validation text={alertText} /> : null}
|
|
472
|
+
</>
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
);
|