Skip to content

Commit

Permalink
feat(suite): Fees redesign
Browse files Browse the repository at this point in the history
feat(components): disable vertical align of SelectBar on demand
  • Loading branch information
enjojoy committed Feb 3, 2025
1 parent e411dee commit bef5516
Show file tree
Hide file tree
Showing 13 changed files with 625 additions and 248 deletions.
67 changes: 46 additions & 21 deletions packages/components/src/components/form/SelectBar/SelectBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,26 @@ import { useElevation } from '../../ElevationContext/ElevationContext';
export const allowedSelectBarFrameProps = ['margin', 'width'] as const satisfies FramePropsKeys[];
type AllowedFrameProps = Pick<FrameProps, (typeof allowedSelectBarFrameProps)[number]>;

const Wrapper = styled.div<TransientProps<AllowedFrameProps> & { $isFullWidth?: boolean }>`
const Wrapper = styled.div<
TransientProps<AllowedFrameProps> & {
$isFullWidth?: boolean;
$shouldRealignToVertical?: boolean;
}
>`
display: flex;
align-items: center;
gap: ${spacingsPx.sm};
width: ${({ $isFullWidth }) => ($isFullWidth ? '100%' : 'auto')};
${breakpointMediaQueries.below_sm} {
flex-direction: column;
align-items: flex-start;
width: 100%;
}
${({ $shouldRealignToVertical }) =>
$shouldRealignToVertical &&
css`
@container ${breakpointMediaQueries.below_sm} {
flex-direction: column;
align-items: flex-start;
width: 100%;
}
`}
${withFrameProps}
`;
Expand All @@ -63,6 +72,7 @@ const Options = styled.div<{
$optionsCount: number;
$isFullWidth?: boolean;
$elevation: Elevation;
$shouldRealignToColumn?: boolean;
}>`
position: relative;
display: grid;
Expand All @@ -74,14 +84,23 @@ const Options = styled.div<{
border-radius: ${borders.radii.full};
width: ${({ $isFullWidth }) => ($isFullWidth ? '100%' : 'auto')};
${breakpointMediaQueries.below_sm} {
grid-auto-flow: row;
width: 100%;
border-radius: ${borders.radii.lg};
}
${({ $shouldRealignToColumn }) =>
$shouldRealignToColumn &&
css`
@container ${breakpointMediaQueries.below_sm} {
grid-auto-flow: row;
width: 100%;
border-radius: ${borders.radii.lg};
}
`}
`;

const Puck = styled.div<{ $optionsCount: number; $selectedIndex: number; $elevation: Elevation }>`
const Puck = styled.div<{
$optionsCount: number;
$selectedIndex: number;
$elevation: Elevation;
$shouldRealignToVertical?: boolean;
}>`
position: absolute;
left: 4px;
top: 4px;
Expand All @@ -98,15 +117,18 @@ const Puck = styled.div<{ $optionsCount: number; $selectedIndex: number; $elevat
${getFocusShadowStyle()}
${breakpointMediaQueries.below_sm} {
left: 4px;
right: 4px;
top: 4px;
width: auto;
height: ${({ $optionsCount }) => getPuckWidth($optionsCount)};
transform: ${({ $selectedIndex: selectedIndex }) =>
`translateY(${getTranslateValue(selectedIndex)})`};
}
${({ $shouldRealignToVertical, $optionsCount, $selectedIndex }) =>
$shouldRealignToVertical &&
css`
@container ${breakpointMediaQueries.below_sm} {
left: 4px;
right: 4px;
top: 4px;
width: auto;
height: ${getPuckWidth($optionsCount)};
transform: translateY(${getTranslateValue($selectedIndex)});
}
`}
`;

const WidthMock = styled.span`
Expand Down Expand Up @@ -166,6 +188,7 @@ export type SelectBarProps<V extends ValueTypes> = {
isDisabled?: boolean;
isFullWidth?: boolean;
className?: string;
shouldRealignToVertical?: boolean;
'data-testid'?: string;
} & AllowedFrameProps;

Expand All @@ -178,6 +201,7 @@ export const SelectBar = <V extends ValueTypes>({
isDisabled = false,
isFullWidth,
className,
shouldRealignToVertical = true,
'data-testid': dataTest,
...rest
}: SelectBarProps<V>) => {
Expand Down Expand Up @@ -238,6 +262,7 @@ export const SelectBar = <V extends ValueTypes>({
<Wrapper
className={className}
$isFullWidth={isFullWidth}
$shouldRealignToVertical={shouldRealignToVertical}
data-testid={dataTest}
{...frameProps}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const constructContainerQueryMaxWidth = (breakpoint: number) =>
`@container (max-width: ${breakpoint}px)`;
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const ClaimModal = ({ onCancel }: ClaimModalModalProps) => {

const {
account,
network,
formState: { errors, isSubmitting },
register,
control,
Expand Down Expand Up @@ -113,6 +114,7 @@ export const ClaimModal = ({ onCancel }: ClaimModalModalProps) => {

<Card paddingType="small" margin={{ vertical: spacings.xs }}>
<Fees
network={network}
control={control}
errors={errors}
register={register}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Inputs } from './Inputs';
export const StakeEthForm = () => {
const {
account,
network,
isConfirmModalOpen,
closeConfirmModal,
signTx,
Expand Down Expand Up @@ -45,6 +46,7 @@ export const StakeEthForm = () => {

<Card paddingType="small" margin={{ top: spacings.xs }}>
<Fees
network={network}
control={control}
errors={errors}
register={register}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ export const RbfFees = () => {
account,
feeInfo,
composedLevels,
network,
} = useRbfContext();

return (
<Fees
network={network}
control={control}
errors={errors}
register={register}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const UnstakeEthForm = () => {
control,
setValue,
getValues,
network,
changeFeeLevel,
feeInfo,
composedLevels,
Expand Down Expand Up @@ -76,6 +77,7 @@ export const UnstakeEthForm = () => {

<Card paddingType="small" margin={{ vertical: spacings.xs }}>
<Fees
network={network}
control={control}
errors={errors}
register={register}
Expand Down
58 changes: 53 additions & 5 deletions packages/suite/src/components/wallet/Fees/CustomFee.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ import {
import { NetworkType } from '@suite-common/wallet-config';
import { FeeInfo, FormState } from '@suite-common/wallet-types';
import { getFeeUnits, getInputState, isInteger } from '@suite-common/wallet-utils';
import { Banner, Column, Grid, Note, Text, useMediaQuery, variables } from '@trezor/components';
import {
Banner,
Column,
Grid,
Icon,
Note,
Row,
Text,
useElevation,
useMediaQuery,
variables,
} from '@trezor/components';
import { FeeLevel } from '@trezor/connect';
import { NumberInput } from '@trezor/product-components';
import { spacings } from '@trezor/theme';
import { HELP_CENTER_TRANSACTION_FEES_URL } from '@trezor/urls';
Expand All @@ -23,6 +35,7 @@ import { useSelector, useTranslation } from 'src/hooks/suite';
import { selectLanguage } from 'src/reducers/suite/suiteReducer';
import { validateDecimals } from 'src/utils/suite/validation';

import { BorderTopWrapper } from './Fees';
import { InputError } from '../InputError';

const FEE_PER_UNIT = 'feePerUnit';
Expand All @@ -36,16 +49,22 @@ interface CustomFeeProps<TFieldValues extends FormState> {
control: Control;
setValue: UseFormSetValue<TFieldValues>;
getValues: UseFormGetValues<TFieldValues>;
changeFeeLimit?: (value: string) => void;
composedFeePerByte: string;
}

const getAverageFee = (levels: FeeLevel[]) => {
if (levels.length > 2) {
return `${levels[1].feePerUnit}`;
}

return `${levels[0].feePerUnit}`;
};

export const CustomFee = <TFieldValues extends FormState>({
networkType,
feeInfo,
register,
control,
changeFeeLimit,
composedFeePerByte,
...props
}: CustomFeeProps<TFieldValues>) => {
Expand All @@ -66,6 +85,7 @@ export const CustomFee = <TFieldValues extends FormState>({

const feePerUnitError = errors.feePerUnit;
const feeLimitError = errors.feeLimit;
const { elevation } = useElevation();

const useFeeLimit = networkType === 'ethereum';
const isComposedFeeRateDifferent =
Expand Down Expand Up @@ -146,7 +166,7 @@ export const CustomFee = <TFieldValues extends FormState>({
feeLimitError?.type === 'feeLimit' ? feeLimitValidationProps : undefined;

return (
<Column gap={spacings.xs}>
<Column gap={spacings.md} margin={{ bottom: spacings.md }}>
<Banner
icon
variant="warning"
Expand All @@ -160,6 +180,35 @@ export const CustomFee = <TFieldValues extends FormState>({
>
<Translation id="TR_CUSTOM_FEE_WARNING" />
</Banner>
<BorderTopWrapper $elevation={elevation}>
<Row
justifyContent="space-between"
margin={{
left: spacings.md,
right: spacings.md,
}}
>
<Text variant="tertiary">
<Translation
id={
networkType === 'ethereum'
? 'TR_AVERAGE_GAS_PRICE'
: 'TR_AVERAGE_FEE'
}
/>
:
</Text>
<Text variant="tertiary">
<Row alignItems="center" gap={spacings.xxs}>
{getAverageFee(feeInfo.levels)} {getFeeUnits(networkType)}
<Icon
name={networkType === 'ethereum' ? 'gasPump' : 'receipt'}
size="mediumLarge"
/>
</Row>
</Text>
</Row>
</BorderTopWrapper>
<Grid gap={spacings.xs} columns={useFeeLimit && !isBelowLaptop ? 2 : 1}>
{useFeeLimit ? (
<NumberInput
Expand All @@ -169,7 +218,6 @@ export const CustomFee = <TFieldValues extends FormState>({
inputState={getInputState(feeLimitError)}
name={FEE_LIMIT}
data-testid={FEE_LIMIT}
onChange={changeFeeLimit}
bottomText={
feeLimitError?.message ? (
<InputError
Expand Down
Loading

0 comments on commit bef5516

Please sign in to comment.