Feat/1147 input setter (#1148)

* feat(console-lite): stretch half page width for xl screens on connect wallet on portfolio page

* feat(console-lite): make InputSetter component reusable

* fix(console-lite): pr comments

* fix(console-lite): failing tests
This commit is contained in:
Elmar 2022-08-31 16:32:53 +01:00 committed by GitHub
parent 3519f1b814
commit 4407a778a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 145 additions and 50 deletions

View File

@ -7,13 +7,13 @@ import {
SliderThumb,
SliderTrack,
SliderRange,
Input,
FormGroup,
Icon,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { BigNumber } from 'bignumber.js';
import { DealTicketEstimates } from './deal-ticket-estimates';
import { InputSetter } from '../input-setter';
import * as constants from './constants';
interface DealTicketSizeProps {
@ -61,7 +61,6 @@ export const DealTicketSize = ({
}: DealTicketSizeProps) => {
const sizeRatios = [0, 25, 50, 75, 100];
const [inputValue, setInputValue] = useState(value);
const [isInputVisible, setIsInputVisible] = useState(false);
const onInputValueChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
@ -84,30 +83,21 @@ export const DealTicketSize = ({
const onButtonValueChange = useCallback(
(size: number) => {
if (isInputVisible) {
setIsInputVisible(false);
}
const newVal = new BigNumber(size)
.decimalPlaces(positionDecimalPlaces)
.toNumber();
onValueChange([newVal]);
setInputValue(newVal);
},
[isInputVisible, onValueChange, positionDecimalPlaces]
[onValueChange, positionDecimalPlaces]
);
const toggleInput = useCallback(() => {
setIsInputVisible(!isInputVisible);
}, [isInputVisible]);
const onInputEnter = useCallback(
(event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
event.stopPropagation();
toggleInput();
}
const onSliderValueChange = useCallback(
(value: number[]) => {
setInputValue(value[0]);
onValueChange(value);
},
[toggleInput]
[onValueChange]
);
return max === 0 ? (
@ -121,7 +111,7 @@ export const DealTicketSize = ({
<SliderRoot
className="mb-2"
value={[value]}
onValueChange={onValueChange}
onValueChange={onSliderValueChange}
step={step}
min={min}
max={max}
@ -160,36 +150,16 @@ export const DealTicketSize = ({
label="Enter Size"
labelFor="trade-size-input"
>
{isInputVisible ? (
<div className="flex items-center">
<Input
id="input-order-size-market"
type="number"
step={step}
min={min}
max={max}
className="w-full"
value={inputValue}
onKeyDown={onInputEnter}
onChange={onInputValueChange}
/>
<button
className="no-underline hover:underline text-blue ml-2"
type="button"
onClick={toggleInput}
>
{t('set')}
</button>
</div>
) : (
<button
className="no-underline hover:underline text-blue"
onClick={toggleInput}
type="button"
>
{value}
</button>
)}
<InputSetter
id="input-order-size-market"
type="number"
step={step}
min={min}
max={max}
className="w-full"
value={inputValue}
onChange={onInputValueChange}
/>
</FormGroup>
</dd>
</div>

View File

@ -0,0 +1 @@
export * from './input-setter';

View File

@ -0,0 +1,64 @@
import React from 'react';
import { render, waitFor, fireEvent } from '@testing-library/react';
import { InputSetter } from './index';
describe('InputSetter Component', () => {
it('should show the correct value and visibility based on props', async () => {
const value = 'Hello';
const isInputVisible = true;
const { getByRole } = await render(
<InputSetter
id="input-order-size-market"
type="number"
className="w-full"
value={value}
isInputVisible={isInputVisible}
onChange={() => false}
/>
);
const input = getByRole('spinbutton');
const btn = getByRole('button');
expect(input).toHaveAttribute('value', value);
expect(btn).toBeTruthy();
});
it('should toggle the visibility of the input when the button is clicked', async () => {
const value = 'Hello';
const isInputVisible = true;
const { getByRole } = await render(
<InputSetter
id="input-order-size-market"
type="number"
className="w-full"
value={value}
isInputVisible={isInputVisible}
onChange={() => false}
/>
);
const btn = getByRole('button');
fireEvent.click(btn);
await waitFor(() => getByRole('button'));
expect(getByRole('button')).toHaveTextContent(value);
});
it('should toggle the visibility of the input when the enter key is pressed', async () => {
const value = 'Hello';
const isInputVisible = true;
const { getByRole } = await render(
<InputSetter
id="input-order-size-market"
name="input-order-size-market"
type="number"
className="w-full"
value={value}
isInputVisible={isInputVisible}
onChange={() => false}
/>
);
fireEvent.keyDown(getByRole('spinbutton'), {
key: 'Enter',
});
await waitFor(() => getByRole('button'));
expect(getByRole('button')).toHaveTextContent(value);
});
});

View File

@ -0,0 +1,56 @@
import React, { useCallback, useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { Input } from '@vegaprotocol/ui-toolkit';
import type { InputProps } from '@vegaprotocol/ui-toolkit';
interface InputSetterProps {
buttonLabel?: string;
value: string | number;
isInputVisible?: boolean;
onValueChange?: () => string;
}
export const InputSetter = ({
buttonLabel = t('set'),
value = '',
isInputVisible = false,
onValueChange,
...props
}: InputSetterProps & InputProps) => {
const [isInputToggled, setIsInputToggled] = useState(isInputVisible);
const toggleInput = useCallback(() => {
setIsInputToggled(!isInputToggled);
}, [isInputToggled]);
const onInputEnter = useCallback(
(event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
event.stopPropagation();
toggleInput();
}
},
[toggleInput]
);
return isInputToggled ? (
<div className="flex items-center">
<Input {...props} value={value} onKeyDown={onInputEnter} />
<button
type="button"
className="no-underline hover:underline text-blue ml-2"
onClick={toggleInput}
>
{buttonLabel}
</button>
</div>
) : (
<button
type="button"
className="no-underline hover:underline text-blue"
onClick={toggleInput}
>
{value}
</button>
);
};

View File

@ -11,7 +11,11 @@ import ConnectWallet from '../wallet-connector';
export const Portfolio = () => {
const { keypair } = useVegaWallet();
if (!keypair) {
return <ConnectWallet />;
return (
<section className="xl:w-1/2">
<ConnectWallet />
</section>
);
}
return (
<Tabs>

View File

@ -55,7 +55,7 @@ type InputAppend = NoPrepend &
type AffixProps = InputPrepend | InputAppend;
type InputProps = InputRootProps & AffixProps;
export type InputProps = InputRootProps & AffixProps;
export const inputStyle = ({
style,