Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(suite): Fix buy/sell/dca buttons #15795

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useArgs } from '@storybook/client-api';
import { Meta, StoryObj } from '@storybook/react';

import { SelectBar as SelectBarComponent, SelectBarProps } from './SelectBar';
import { fillTypes, SelectBar as SelectBarComponent, SelectBarProps } from './SelectBar';
import { IconName } from '../../Icon/Icon';

const options = [
{ label: 'low', value: 'low' },
{ label: 'medium', value: 'medium' },
{ label: 'high', value: 'high' },
{ label: 'custom', value: 'custom' },
{ label: 'custom', value: 'custom', icon: 'clock' as IconName },
];

const meta: Meta = {
Expand All @@ -18,6 +19,7 @@ const meta: Meta = {
selectedOption: 'low',
isDisabled: false,
isFullWidth: undefined,
fillType: 'default',
},
argTypes: {
label: {
Expand Down Expand Up @@ -50,6 +52,12 @@ const meta: Meta = {
type: 'boolean',
},
},
fillType: {
control: {
type: 'radio',
},
options: fillTypes,
},
},
component: SelectBarComponent,
} as unknown as Meta;
Expand Down
59 changes: 43 additions & 16 deletions packages/components/src/components/form/SelectBar/SelectBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ import {
withFrameProps,
} from '../../../utils/frameProps';
import { TransientProps } from '../../../utils/transientProps';
import { Icon, IconName } from '../../Icon/Icon';
import { Row } from '../../Flex/Flex';

export const allowedSelectBarFrameProps = ['margin', 'width'] as const satisfies FramePropsKeys[];
type AllowedFrameProps = Pick<FrameProps, (typeof allowedSelectBarFrameProps)[number]>;

export const fillTypes = ['none', 'default'] as const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should create a common fill types like for other props, it's used in many components.

export type FillType = (typeof fillTypes)[number];

const Wrapper = styled.div<TransientProps<AllowedFrameProps> & { $isFullWidth?: boolean }>`
display: flex;
align-items: center;
Expand Down Expand Up @@ -63,14 +68,16 @@ const Options = styled.div<{
$optionsCount: number;
$isFullWidth?: boolean;
$elevation: Elevation;
$fillType: FillType;
}>`
position: relative;
display: grid;
grid-auto-columns: ${({ $optionsCount }) => `minmax(${getPuckWidth($optionsCount)}, 1fr)`};
grid-auto-flow: column;
gap: ${spacingsPx.xxs};
padding: ${spacingsPx.xxs};
background: ${mapElevationToBackground};
background: ${({ $fillType, theme, $elevation }) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do it the other way around, unset the background when fillType is none. Then you don't have to pass all the props to the mapElevationToBackground.

$fillType === 'default' ? mapElevationToBackground({ theme, $elevation }) : undefined};
border-radius: ${borders.radii.full};
width: ${({ $isFullWidth }) => ($isFullWidth ? '100%' : 'auto')};
Expand Down Expand Up @@ -156,6 +163,7 @@ type ValueTypes = number | string | boolean;
type Option<V extends ValueTypes> = {
label: ReactNode;
value: V;
icon?: IconName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iconName

};

export type SelectBarProps<V extends ValueTypes> = {
Expand All @@ -167,6 +175,7 @@ export type SelectBarProps<V extends ValueTypes> = {
isFullWidth?: boolean;
className?: string;
'data-testid'?: string;
fillType?: FillType;
} & AllowedFrameProps;

// Generic type V is determined by selectedOption/options values
Expand All @@ -178,6 +187,7 @@ export const SelectBar = <V extends ValueTypes>({
isDisabled = false,
isFullWidth,
className,
fillType = 'default',
'data-testid': dataTest,
...rest
}: SelectBarProps<V>) => {
Expand Down Expand Up @@ -247,6 +257,7 @@ export const SelectBar = <V extends ValueTypes>({
$optionsCount={options.length}
$isFullWidth={isFullWidth}
$elevation={elevation}
$fillType={fillType}
>
<Puck
$optionsCount={options.length}
Expand All @@ -256,22 +267,38 @@ export const SelectBar = <V extends ValueTypes>({
onKeyDown={handleKeyboardNav}
/>

{options.map(option => (
<Option
key={String(option.value)}
onClick={handleOptionClick(option)}
$isDisabled={!!isDisabled}
$isSelected={
selectedOptionIn !== undefined
? selectedOptionIn === option.value
: false
}
data-testid={`select-bar/${String(option.value)}`}
>
{options.map(option => {
const content = option.icon ? (
<Row gap={spacings.xs}>
<Icon
name={option.icon}
size="medium"
variant={selectedOptionIn === option.value ? 'primary' : undefined}
/>
<span>{option.label}</span>
</Row>
) : (
<span>{option.label}</span>
<WidthMock>{option.label}</WidthMock>
</Option>
))}
);

return (
<Option
key={String(option.value)}
onClick={handleOptionClick(option)}
$isDisabled={!!isDisabled}
$isSelected={
selectedOptionIn !== undefined
? selectedOptionIn === option.value
: false
}
data-testid={`select-bar/${String(option.value)}`}
>
{content}

<WidthMock>{content}</WidthMock>
</Option>
);
})}
</Options>
</Wrapper>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import { Row } from '@trezor/components';
import { IconName, SelectBar } from '@trezor/components';
import { Route } from '@suite-common/suite-types';

import { CoinmarketLayoutNavigationItem } from 'src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketLayoutNavigation/CoinmarketLayoutNavigationItem';
import { Translation } from '../../../../../../components/suite';
import { goto } from '../../../../../../actions/suite/routerActions';
import { useDispatch, useSelector } from '../../../../../../hooks/suite';

export const CoinmarketLayoutNavigation = () => (
<Row>
<CoinmarketLayoutNavigationItem
route="wallet-coinmarket-buy"
title="TR_NAV_BUY"
icon="plus"
/>
<CoinmarketLayoutNavigationItem
route="wallet-coinmarket-sell"
title="TR_NAV_SELL"
icon="minus"
/>
<CoinmarketLayoutNavigationItem
route="wallet-coinmarket-dca"
title="TR_NAV_DCA"
icon="clock"
/>
</Row>
);
const options = [
{
label: <Translation id="TR_NAV_BUY" />,
value: 'wallet-coinmarket-buy' as Route['name'],
icon: 'plus' as IconName,
},
{
label: <Translation id="TR_NAV_SELL" />,
value: 'wallet-coinmarket-sell' as Route['name'],
icon: 'minus' as IconName,
},
{
label: <Translation id="TR_NAV_DCA" />,
value: 'wallet-coinmarket-dca' as Route['name'],
icon: 'clock' as IconName,
},
];

export const CoinmarketLayoutNavigation = () => {
const dispatch = useDispatch();
const routeName = useSelector(state => state.router.route?.name);
const onChange = (newRoute: Route['name']) => {
dispatch(goto(newRoute));
};

return <SelectBar selectedOption={routeName} options={options} onChange={onChange} />;
};
Loading