-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
103 changes: 103 additions & 0 deletions
103
src/components/currency-input/CurrencyInput.stories.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"; | ||
|
||
<Meta title="Form/CurrencyInput" component={CurrencyInput} /> | ||
|
||
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 ( | ||
|
||
<div | ||
className={css({ | ||
width: "400px", | ||
})} | ||
> | ||
<CurrencyInput {...args} value={value} currencies={currencies} onChange={onChange} /> | ||
</div> | ||
); }; | ||
|
||
# Input | ||
|
||
<Canvas isColumn> | ||
<Story name="Small" args={{ placeholder: "Input Field", size: INPUT_SIZE.small }}> | ||
{Template.bind({})} | ||
</Story> | ||
<Story name="Medium" args={{ placeholder: "Input Field" }}> | ||
{Template.bind({})} | ||
</Story> | ||
<Story name="Disabled" args={{ placeholder: "Disabled Field", disabled: true }}> | ||
{Template.bind({})} | ||
</Story> | ||
<Story | ||
name="Secondary disabled" | ||
args={{ | ||
placeholder: "Disabled Secondary Small", | ||
disabled: true, | ||
size: INPUT_SIZE.small, | ||
kind: INPUT_KIND.secondary, | ||
}} | ||
> | ||
{Template.bind({})} | ||
</Story> | ||
<Story name="Secondary" args={{ placeholder: "Secondary input", kind: INPUT_KIND.secondary }}> | ||
{Template.bind({})} | ||
</Story> | ||
<Story name="Error" args={{ placeholder: "Error Field", error: true }}> | ||
{Template.bind({})} | ||
</Story> | ||
<Story name="With Start Enhancer" args={{ placeholder: "With start enchancer", startEnhancer: <HeartIcon /> }}> | ||
{Template.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
<ArgsTable of={CurrencyInput} /> | ||
|
||
### Usage: | ||
|
||
To use, import the component `CurrencyInput` from `@nilfoundation/ui-kit`. | ||
|
||
<Source | ||
language="tsx" | ||
dark | ||
format={true} | ||
code={` | ||
import {CurrencyInput} from "@nilfoundation/ui-kit"; | ||
... | ||
const onChange = ({ currency, amount }) => { | ||
setValue({ currency, amount }); | ||
}; | ||
const currencies = [ | ||
"USDT", | ||
"BTC", | ||
"ETH", | ||
"BNB", | ||
"ADA", | ||
"XRP", | ||
]; | ||
<CurrencyInput placeholder="Currency input field" size={INPUT_SIZE.small} currencies={currencies} onChange={onChange} /> | ||
`} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(<CurrencyInput size={INPUT_SIZE.medium} value={{ currency: "USDT", amount: "1" }} currencies={[]} />); | ||
|
||
const inputElement = screen.getByRole("spinbutton"); | ||
expect(inputElement).toBeInTheDocument(); | ||
}); | ||
|
||
it("handles input changes", async () => { | ||
const handleChange = jest.fn(); | ||
render( | ||
<CurrencyInput | ||
size={INPUT_SIZE.medium} | ||
onChange={handleChange} | ||
value={{ currency: "USDT", amount: "1" }} | ||
currencies={[]} | ||
></CurrencyInput> | ||
); | ||
|
||
const inputElement = screen.getByRole("spinbutton"); | ||
userEvent.type(inputElement, "100"); | ||
|
||
await waitFor(() => expect(handleChange).toHaveBeenCalled()); | ||
}); | ||
|
||
it("renders ssr without crashing", () => { | ||
createComponentSSRTest( | ||
<CurrencyInput size={INPUT_SIZE.medium} value={{ currency: "USDT", amount: "1" }} currencies={[]} /> | ||
); | ||
}); | ||
|
||
// Add more tests as needed | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 = <Currency extends string>({ | ||
value, | ||
onChange, | ||
currencies, | ||
className, | ||
label, | ||
disabled = false, | ||
caption, | ||
placeholder, | ||
overrides, | ||
size = INPUT_SIZE.medium, | ||
startEnhancer, | ||
error, | ||
required, | ||
kind, | ||
}: CurrencyInputProps<Currency>) => { | ||
const mergedInputOverrides = getMergedOverrides(inputOverrides, overrides); | ||
|
||
return ( | ||
<div className={className}> | ||
<FormControl label={label} caption={caption} error={error} required={required} size={size}> | ||
<Input | ||
startEnhancer={startEnhancer} | ||
disabled={disabled} | ||
overrides={mergedInputOverrides} | ||
placeholder={placeholder} | ||
type="number" | ||
value={value.amount} | ||
onChange={(e) => { | ||
onChange && | ||
onChange({ | ||
currency: value.currency, | ||
amount: e.currentTarget.value, | ||
}); | ||
}} | ||
size={size} | ||
kind={kind} | ||
endEnhancer={ | ||
<Select | ||
disabled={disabled} | ||
options={currencies.map((currency) => ({ | ||
label: currency, | ||
id: currency, | ||
}))} | ||
searchable={false} | ||
overrides={selectOverrides} | ||
placeholder="" | ||
clearable={false} | ||
onChange={(params) => { | ||
onChange && | ||
onChange({ | ||
currency: params.value[0].label as Currency, | ||
amount: value.amount, | ||
}); | ||
}} | ||
value={[ | ||
{ | ||
label: value.currency, | ||
id: value.currency, | ||
}, | ||
]} | ||
size={mapInputSizeToSelectSize(size)} | ||
error={error !== undefined} | ||
/> | ||
} | ||
/> | ||
</FormControl> | ||
</div> | ||
); | ||
}; | ||
|
||
export default CurrencyInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as CurrencyInput } from "./CurrencyInput"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { InputOverrides } from "baseui/input"; | ||
|
||
export const inputOverrides: InputOverrides = { | ||
Input: { | ||
style: { | ||
"::-webkit-outer-spin-button": { | ||
WebkitAppearance: "none", | ||
margin: 0, | ||
}, | ||
"::-webkit-inner-spin-button": { | ||
WebkitAppearance: "none", | ||
margin: 0, | ||
}, | ||
"-moz-appearance": "textfield", | ||
}, | ||
}, | ||
}; | ||
|
||
export const selectOverrides = { | ||
ControlContainer: { | ||
style: { | ||
width: "100px", | ||
backgroundColor: "transparent", | ||
boxShadow: "none", | ||
":has(input:focus-within)": { | ||
boxShadow: "none", | ||
}, | ||
":hover": { | ||
backgroundColor: "transparent", | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { FormControlProps } from "../form-control"; | ||
import { InputProps } from "../input"; | ||
|
||
export type CurrencyInputProps<Currency extends string> = Pick< | ||
InputProps, | ||
"placeholder" | "disabled" | "overrides" | "size" | "startEnhancer" | "kind" | ||
> & | ||
Pick<FormControlProps, "caption" | "label" | "error" | "required"> & { | ||
className?: string; | ||
value: { currency: Currency; amount: string }; | ||
onChange?: (value: { currency: Currency; amount: string }) => void; | ||
currencies: Currency[]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { INPUT_SIZE } from "../input"; | ||
import { SELECT_SIZE } from "../select"; | ||
|
||
export const mapInputSizeToSelectSize = (size: INPUT_SIZE) => { | ||
switch (size) { | ||
case INPUT_SIZE.small: | ||
return SELECT_SIZE.small; | ||
case INPUT_SIZE.medium: | ||
return SELECT_SIZE.medium; | ||
} | ||
}; |