From 287b184d036d9f572c736ae15b9a10a8c716f657 Mon Sep 17 00:00:00 2001 From: ukorvl Date: Mon, 16 Dec 2024 15:43:27 +0400 Subject: [PATCH] add CurrencyInput component --- .../currency-input/CurrencyInput.stories.mdx | 103 ++++++++++++++++++ .../currency-input/CurrencyInput.test.tsx | 40 +++++++ .../currency-input/CurrencyInput.tsx | 80 ++++++++++++++ src/components/currency-input/index.ts | 1 + src/components/currency-input/overrides.ts | 33 ++++++ src/components/currency-input/types.ts | 13 +++ src/components/currency-input/utils.ts | 11 ++ 7 files changed, 281 insertions(+) create mode 100644 src/components/currency-input/CurrencyInput.stories.mdx create mode 100644 src/components/currency-input/CurrencyInput.test.tsx create mode 100644 src/components/currency-input/CurrencyInput.tsx create mode 100644 src/components/currency-input/index.ts create mode 100644 src/components/currency-input/overrides.ts create mode 100644 src/components/currency-input/types.ts create mode 100644 src/components/currency-input/utils.ts diff --git a/src/components/currency-input/CurrencyInput.stories.mdx b/src/components/currency-input/CurrencyInput.stories.mdx new file mode 100644 index 00000000..394278a5 --- /dev/null +++ b/src/components/currency-input/CurrencyInput.stories.mdx @@ -0,0 +1,103 @@ +import { Canvas, Meta, Story, ArgsTable, Source } from "@storybook/blocks"; +import CurrencyInput from "./CurrencyInput"; +import { useState } from "react"; +import { useStyletron } from "baseui"; +import { INPUT_SIZE, INPUT_KIND } from "../input"; +import { HeartIcon } from "../icons"; + + + +export const Template = ({ ...args }) => { + const [value, setValue] = useState({ + currency: "USDT", + amount: "", + }); + const [css] = useStyletron(); + const currencies = [ + "USDT", + "BTC", + "ETH", + "BNB", + "ADA", + "XRP", + ]; + +const onChange = ({ currency, amount }) => { +setValue({ currency, amount }); +}; + +return ( + +
+ +
+); }; + +# Input + + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + }}> + {Template.bind({})} + + + + + +### Usage: + +To use, import the component `CurrencyInput` from `@nilfoundation/ui-kit`. + + { + setValue({ currency, amount }); + }; + + const currencies = [ + "USDT", + "BTC", + "ETH", + "BNB", + "ADA", + "XRP", + ]; + + + +`} +/> diff --git a/src/components/currency-input/CurrencyInput.test.tsx b/src/components/currency-input/CurrencyInput.test.tsx new file mode 100644 index 00000000..0729c823 --- /dev/null +++ b/src/components/currency-input/CurrencyInput.test.tsx @@ -0,0 +1,40 @@ +import { screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { render } from "../../test-utils/render"; +import { createComponentSSRTest } from "../../test-utils/createComponentSSRTest"; +import CurrencyInput from "./CurrencyInput"; +import { INPUT_SIZE } from "../input"; + +describe("CurrencyInput", () => { + it("renders without crashing", () => { + render(); + + const inputElement = screen.getByRole("spinbutton"); + expect(inputElement).toBeInTheDocument(); + }); + + it("handles input changes", async () => { + const handleChange = jest.fn(); + render( + + ); + + const inputElement = screen.getByRole("spinbutton"); + userEvent.type(inputElement, "100"); + + await waitFor(() => expect(handleChange).toHaveBeenCalled()); + }); + + it("renders ssr without crashing", () => { + createComponentSSRTest( + + ); + }); + + // Add more tests as needed +}); diff --git a/src/components/currency-input/CurrencyInput.tsx b/src/components/currency-input/CurrencyInput.tsx new file mode 100644 index 00000000..ab6fb983 --- /dev/null +++ b/src/components/currency-input/CurrencyInput.tsx @@ -0,0 +1,80 @@ +import { FormControl } from "../form-control"; +import { INPUT_SIZE, Input } from "../input"; +import { Select } from "../select"; +import { CurrencyInputProps } from "./types"; +import { getMergedOverrides } from "../../shared/utils/getMergedOverrides"; +import { inputOverrides, selectOverrides } from "./overrides"; +import { mapInputSizeToSelectSize } from "./utils"; + +const CurrencyInput = ({ + value, + onChange, + currencies, + className, + label, + disabled = false, + caption, + placeholder, + overrides, + size = INPUT_SIZE.medium, + startEnhancer, + error, + required, + kind, +}: CurrencyInputProps) => { + const mergedInputOverrides = getMergedOverrides(inputOverrides, overrides); + + return ( +
+ + { + onChange && + onChange({ + currency: value.currency, + amount: e.currentTarget.value, + }); + }} + size={size} + kind={kind} + endEnhancer={ +