-
-
Notifications
You must be signed in to change notification settings - Fork 259
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
export type FillType = (typeof fillTypes)[number]; | ||
|
||
const Wrapper = styled.div<TransientProps<AllowedFrameProps> & { $isFullWidth?: boolean }>` | ||
display: flex; | ||
align-items: center; | ||
|
@@ -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 }) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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')}; | ||
|
@@ -156,6 +163,7 @@ type ValueTypes = number | string | boolean; | |
type Option<V extends ValueTypes> = { | ||
label: ReactNode; | ||
value: V; | ||
icon?: IconName; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. iconName |
||
}; | ||
|
||
export type SelectBarProps<V extends ValueTypes> = { | ||
|
@@ -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 | ||
|
@@ -178,6 +187,7 @@ export const SelectBar = <V extends ValueTypes>({ | |
isDisabled = false, | ||
isFullWidth, | ||
className, | ||
fillType = 'default', | ||
'data-testid': dataTest, | ||
...rest | ||
}: SelectBarProps<V>) => { | ||
|
@@ -247,6 +257,7 @@ export const SelectBar = <V extends ValueTypes>({ | |
$optionsCount={options.length} | ||
$isFullWidth={isFullWidth} | ||
$elevation={elevation} | ||
$fillType={fillType} | ||
> | ||
<Puck | ||
$optionsCount={options.length} | ||
|
@@ -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> | ||
); | ||
|
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} />; | ||
}; |
There was a problem hiding this comment.
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.