Skip to content

Commit

Permalink
refactor(input): remove InputTextField component
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Feb 23, 2024
1 parent 7a00427 commit cc4de7e
Show file tree
Hide file tree
Showing 21 changed files with 271 additions and 261 deletions.
102 changes: 60 additions & 42 deletions src/app/components/bitcoin-custom-fee/bitcoin-custom-fee.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dispatch, SetStateAction, useCallback, useRef } from 'react';

import { Form, Formik } from 'formik';
import { Form, Formik, useField } from 'formik';
import { Stack, styled } from 'leather-styles/jsx';
import * as yup from 'yup';

Expand All @@ -9,15 +9,41 @@ import { createMoney } from '@shared/models/money.model';

import { openInNewTab } from '@app/common/utils/open-in-new-tab';
import { PreviewButton } from '@app/components/preview-button';
import { Input } from '@app/ui/components/input/input';
import { Link } from '@app/ui/components/link/link';

import { OnChooseFeeArgs } from '../bitcoin-fees-list/bitcoin-fees-list';
import { TextInputField } from '../text-input-field';
import { BitcoinCustomFeeFiat } from './bitcoin-custom-fee-fiat';
import { useBitcoinCustomFee } from './hooks/use-bitcoin-custom-fee';

const feeInputLabel = 'sats/vB';

interface BitcoinCustomFeeInputProps {
hasInsufficientBalanceError: boolean;
onClick(): void;
onChange?(e: React.ChangeEvent<HTMLInputElement>): void;
}
function BitcoinCustomFeeInput({
hasInsufficientBalanceError,
onClick,
onChange,
}: BitcoinCustomFeeInputProps) {
const [field] = useField('feeRate');
return (
<Input.Root hasError={hasInsufficientBalanceError}>
<Input.Label>{feeInputLabel}</Input.Label>
<Input.Field
onClick={onClick}
{...field}
onChange={e => {
field.onChange(e);
onChange?.(e);
}}
/>
</Input.Root>
);
}

interface BitcoinCustomFeeProps {
amount: number;
customFeeInitialValue: string;
Expand Down Expand Up @@ -82,48 +108,40 @@ export function BitcoinCustomFee({
validateOnMount={false}
validationSchema={validationSchema}
>
{props => {
return (
<Form>
<Stack gap="space.06" mt="space.02">
<Stack gap="space.05">
<styled.span color="ink.text-subdued" textStyle="body.02" maxWidth="21.5rem">
Higher fee rates typically lead to faster confirmation times.
<Link
ml="space.01"
onClick={() => openInNewTab('https://buybitcoinworldwide.com/fee-calculator/')}
textStyle="body.02"
>
View fee calculator
</Link>
</styled.span>
<Stack gap="space.01">
<TextInputField
hasError={hasInsufficientBalanceError}
label={feeInputLabel}
name="feeRate"
placeholder={feeInputLabel}
onClick={async () => {
feeInputRef?.current?.focus();
await props.setValues({ ...props.values });
}}
onChange={e => {
setCustomFeeInitialValue((e.target as HTMLInputElement).value);
}}
inputRef={feeInputRef}
/>
<BitcoinCustomFeeFiat
amount={amount}
isSendingMax={isSendingMax}
recipient={recipient}
/>
</Stack>
{props => (
<Form>
<Stack gap="space.06" mt="space.02">
<Stack gap="space.05">
<styled.span color="ink.text-subdued" textStyle="body.02" maxWidth="21.5rem">
Higher fee rates typically lead to faster confirmation times.
<Link
ml="space.01"
onClick={() => openInNewTab('https://buybitcoinworldwide.com/fee-calculator/')}
textStyle="body.02"
>
View fee calculator
</Link>
</styled.span>
<BitcoinCustomFeeInput
hasInsufficientBalanceError={hasInsufficientBalanceError}
onClick={async () => {
feeInputRef?.current?.focus();
await props.setValues({ ...props.values });
}}
onChange={e => setCustomFeeInitialValue((e.target as HTMLInputElement).value)}
/>
<Stack gap="space.01">
<BitcoinCustomFeeFiat
amount={amount}
isSendingMax={isSendingMax}
recipient={recipient}
/>
</Stack>
<PreviewButton isDisabled={!props.values.feeRate} text="Use custom fee" />
</Stack>
</Form>
);
}}
<PreviewButton isDisabled={!props.values.feeRate} text="Use custom fee" />
</Stack>
</Form>
)}
</Formik>
);
}
21 changes: 6 additions & 15 deletions src/app/components/error-label.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import { css } from 'leather-styles/css';
import { HStack, HstackProps } from 'leather-styles/jsx';

import { Flag, type FlagProps } from '@app/ui/components/flag/flag';
import { ErrorCircleIcon } from '@app/ui/icons/error-circle-icon';

export function ErrorLabel({ children, ...rest }: HstackProps) {
export function ErrorLabel({ children, ...rest }: FlagProps) {
return (
<HStack
alignItems="flex-start"
className={css({
'& svg': {
mt: '2px',
},
})}
<Flag
img={<ErrorCircleIcon variant="small" />}
spacing="space.02"
color="red.action-primary-default"
gap="space.02"
textAlign="left"
textStyle="body.02"
{...rest}
>
<ErrorCircleIcon />
{children}
</HStack>
</Flag>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useNavigate } from 'react-router-dom';

import { Formik } from 'formik';
import { Formik, useField } from 'formik';
import { Stack } from 'leather-styles/jsx';

import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';
Expand All @@ -13,15 +13,25 @@ import { getBitcoinTxValue } from '@app/common/transactions/bitcoin/utils';
import { BitcoinCustomFeeFiat } from '@app/components/bitcoin-custom-fee/bitcoin-custom-fee-fiat';
import { BitcoinTransactionItem } from '@app/components/bitcoin-transaction-item/bitcoin-transaction-item';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { TextInputField } from '@app/components/text-input-field';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { Input } from '@app/ui/components/input/input';
import { Caption } from '@app/ui/components/typography/caption';

import { useBtcIncreaseFee } from '../hooks/use-btc-increase-fee';
import { IncreaseFeeActions } from './increase-fee-actions';

const feeInputLabel = 'sats/vB';

function BitcoinFeeIncreaseField() {
const [field] = useField('feeRate');
return (
<Input.Root>
<Input.Field placeholder={feeInputLabel} {...field} />
<Input.Label>Fee rate</Input.Label>
</Input.Root>
);
}

interface IncreaseBtcFeeFormProps {
btcTx: BitcoinTx;
}
Expand Down Expand Up @@ -53,7 +63,7 @@ export function IncreaseBtcFeeForm({ btcTx }: IncreaseBtcFeeFormProps) {
{btcTx && <BitcoinTransactionItem transaction={btcTx} />}
<Stack gap="space.04">
<Stack gap="space.01">
<TextInputField label={feeInputLabel} name="feeRate" placeholder={feeInputLabel} />
<BitcoinFeeIncreaseField />
<BitcoinCustomFeeFiat
recipient={recipient}
isSendingMax={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,11 @@ export function AmountField({
<Box mt="12px">{switchableAmount && switchableAmount}</Box>
</Flex>
{showError && (
<ErrorLabel
data-testid={SendCryptoAssetSelectors.AmountFieldInputErrorLabel}
justifyContent="center"
>
{meta.error}
</ErrorLabel>
<Flex>
<ErrorLabel data-testid={SendCryptoAssetSelectors.AmountFieldInputErrorLabel}>
{meta.error}
</ErrorLabel>
</Flex>
)}
{bottomInputOverlay}
</Stack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function MemoField() {
const showError = useShowFieldError(name);

return (
<Box width="100%">
<Box width="100%" mt="space.04">
<Input.Root hasError={!!showError}>
<Input.Label>Memo</Input.Label>
<Input.Field data-testid={SendCryptoAssetSelectors.MemoFieldInput} {...field} />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ComponentProps } from 'react';

import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
import { styled } from 'leather-styles/jsx';

interface SelectAccountButtonProps extends ComponentProps<typeof styled.button> {
onClick(): void;
}
export function SelectAccountButton({ onClick, ...props }: SelectAccountButtonProps) {
function preventFocusOfUnderlyingInput(e: React.MouseEvent) {
e.preventDefault();
}

return (
<styled.button
type="button"
color="accent.text-primary"
textStyle="label.03"
_hover={{ color: 'accent.action-primary-hover' }}
data-testid={SendCryptoAssetSelectors.RecipientChooseAccountButton}
fontWeight={500}
onMouseDown={e => preventFocusOfUnderlyingInput(e)}
onClick={e => {
// Improves UX of selecting a recipient from the window. As the button
// to open the drawer is inside the input, we force focus the button,
// such that the focus is taken away from the input in background
(e.target as HTMLButtonElement).focus();
onClick?.();
}}
zIndex={9}
{...props}
>
Select account
</styled.button>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,27 @@ import { useEffect } from 'react';

import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
import { useField, useFormikContext } from 'formik';
import { Box } from 'leather-styles/jsx';

import { BitcoinSendFormValues, StacksSendFormValues } from '@shared/models/form.model';

import { TextInputField } from '@app/components/text-input-field';
import { Input } from '@app/ui/components/input/input';

interface RecipientFieldProps {
isDisabled?: boolean;
label?: string;
labelAction?: string;
name: string;
onBlur?(): void;
onClickLabelAction?(): void;
placeholder: string;
topInputOverlay?: React.JSX.Element;
rightLabel?: React.JSX.Element;
}
export function RecipientField({
isDisabled,
label,
labelAction,
name,
onBlur,
onClickLabelAction,
placeholder,
topInputOverlay,
rightLabel,
isDisabled,
onBlur,
}: RecipientFieldProps) {
const [field] = useField(name);
const { setFieldValue } = useFormikContext<BitcoinSendFormValues | StacksSendFormValues>();
Expand All @@ -35,17 +32,23 @@ export function RecipientField({
}, [name, field.value, setFieldValue]);

return (
<TextInputField
dataTestId={SendCryptoAssetSelectors.RecipientFieldInput}
isDisabled={isDisabled}
label={label}
labelAction={labelAction}
minHeight="76px"
name={name}
onBlur={onBlur}
onClickLabelAction={onClickLabelAction}
placeholder={placeholder}
topInputOverlay={topInputOverlay}
/>
<Box width="100%" position="relative" mb="space.02">
<Input.Root shrink>
<Box pos="absolute" right="space.03" zIndex={15} top="9px">
{rightLabel}
</Box>
<Input.Label>{topInputOverlay}</Input.Label>
<Input.Field
data-testid={SendCryptoAssetSelectors.RecipientFieldInput}
placeholder="Recipient"
disabled={isDisabled}
{...field}
onBlur={e => {
field.onBlur(e);
onBlur?.();
}}
/>
</Input.Root>
</Box>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function RecipientAddressDisplayer({ address }: RecipientAddressDisplayer
}, [analytics, onCopy]);

return (
<HStack alignItems="center" justifyContent="space-between" mb="space.04" width="100%">
<HStack mb="space.04" width="100%" px="space.04" mt="space.02">
<styled.span
textStyle="caption.02"
data-testid={SendCryptoAssetSelectors.RecipientBnsAddressLabel}
Expand Down
Loading

0 comments on commit cc4de7e

Please sign in to comment.