Commit d290adb0 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat: add medium-button and use it nft bag for removal (#5014)

* add medium-button and use it nft bag for removal

* close icon hover states

* update bag row to use correct hover background color

* update x to opacity effect

* pr feedback
parent ac4e64db
......@@ -365,3 +365,34 @@ export function ButtonRadioChecked({ active = false, children, ...rest }: { acti
)
}
}
export const MediumButton = styled.button`
align-items: center;
background-color: ${({ theme }) => theme.backgroundInteractive};
border-radius: 16px;
border: 0;
color: ${({ theme }) => theme.textPrimary};
cursor: pointer;
display: flex;
flex-direction: row;
font-weight: 600;
gap: 12px;
justify-content: center;
padding: 16px;
transition: 150ms ease background-color opacity;
:disabled {
background-color: ${({ theme }) => theme.backgroundInteractive};
cursor: default;
opacity: 0.6;
}
:hover {
background-color: ${({ theme }) => theme.stateOverlayHover};
}
:active {
background-color: ${({ theme }) => theme.stateOverlayPressed};
}
:focus {
background-color: ${({ theme }) => theme.stateOverlayPressed};
}
`
import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex'
import { BagCloseIcon } from 'nft/components/icons'
import { roundAndPluralize } from 'nft/utils/roundAndPluralize'
......@@ -25,6 +24,23 @@ const ControlRow = styled.div`
flex-direction: row;
justify-content: space-between;
`
const IconWrapper = styled.button`
background-color: transparent;
border-radius: 8px;
border: none;
color: ${({ theme }) => theme.textPrimary};
cursor: pointer;
display: flex;
padding: 2px;
opacity: 1;
transition: 125ms ease opacity;
:hover {
opacity: 0.6;
}
:active {
opacity: 0.4;
}
`
interface BagHeaderProps {
numberOfAssets: number
toggleBag: () => void
......@@ -37,9 +53,9 @@ export const BagHeader = ({ numberOfAssets, toggleBag, resetFlow, isProfilePage
<Column gap="4" paddingX="32" marginBottom="20">
<Row className={styles.header}>
<ThemedText.HeadlineSmall>{isProfilePage ? 'Sell NFTs' : 'My bag'}</ThemedText.HeadlineSmall>
<Box display="flex" padding="2" color="textPrimary" cursor="pointer" onClick={toggleBag}>
<IconWrapper onClick={toggleBag}>
<BagCloseIcon />
</Box>
</IconWrapper>
</Row>
{numberOfAssets > 0 && (
<ControlRow>
......
import { style } from '@vanilla-extract/css'
import { bodySmall, buttonTextSmall } from 'nft/css/common.css'
import { bodySmall } from 'nft/css/common.css'
import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css'
export const bagRow = style([
......@@ -16,7 +16,7 @@ export const bagRow = style([
marginLeft: '-4px',
marginRight: '-4px',
':hover': {
background: themeVars.colors.backgroundModule,
background: themeVars.colors.stateOverlayHover,
},
},
])
......@@ -112,17 +112,6 @@ export const removeButton = style([
},
])
export const removeBagRowButton = style([
buttonTextSmall,
sprinkles({
background: 'backgroundInteractive',
color: 'textPrimary',
paddingX: '14',
paddingY: '12',
borderRadius: '12',
}),
])
export const bagRowImage = sprinkles({
width: '56',
height: '56',
......
import { BigNumber } from '@ethersproject/bignumber'
import { formatEther } from '@ethersproject/units'
import clsx from 'clsx'
import { MediumButton } from 'components/Button'
import { TimedLoader } from 'nft/components/bag/TimedLoader'
import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex'
......@@ -19,9 +20,18 @@ import { GenieAsset, UpdatedGenieAsset } from 'nft/types'
import { ethNumberStandardFormatter, formatWeiToDecimal, getAssetHref } from 'nft/utils'
import { MouseEvent, useCallback, useEffect, useReducer, useState } from 'react'
import { Link } from 'react-router-dom'
import styled from 'styled-components/macro'
import * as styles from './BagRow.css'
const RemoveButton = styled(MediumButton)`
border-radius: 12px;
font-size: 14px;
line-height: 16px;
margin-left: 16px;
padding: 12px 14px;
`
const NoContentContainer = () => (
<Box position="relative" background="loadingBackground" className={styles.bagRowImage}>
<Box
......@@ -59,7 +69,7 @@ export const BagRow = ({ asset, usdPrice, removeAsset, showRemove, grayscale, is
const [cardHovered, setCardHovered] = useState(false)
const handleMouseEnter = useCallback(() => setCardHovered(true), [])
const handleMouseLeave = useCallback(() => setCardHovered(false), [])
const showRemoveButton = showRemove && cardHovered
const showRemoveButton = Boolean(showRemove && cardHovered && !isMobile)
const assetEthPrice = asset.updatedPriceInfo ? asset.updatedPriceInfo.ETHPrice : asset.priceInfo.ETHPrice
const assetEthPriceFormatted = formatWeiToDecimal(assetEthPrice)
......@@ -68,6 +78,15 @@ export const BagRow = ({ asset, usdPrice, removeAsset, showRemove, grayscale, is
true
)
const handleRemoveClick = useCallback(
(e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault()
e.stopPropagation()
removeAsset([asset])
},
[asset, removeAsset]
)
return (
<Link to={getAssetHref(asset)} style={{ textDecoration: 'none' }}>
<Row className={styles.bagRow} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
......@@ -75,11 +94,7 @@ export const BagRow = ({ asset, usdPrice, removeAsset, showRemove, grayscale, is
<Box
display={showRemove && isMobile ? 'block' : 'none'}
className={styles.removeAssetOverlay}
onClick={(e: MouseEvent) => {
e.preventDefault()
e.stopPropagation()
removeAsset([asset])
}}
onClick={handleRemoveClick}
transition="250"
zIndex="1"
>
......@@ -112,19 +127,7 @@ export const BagRow = ({ asset, usdPrice, removeAsset, showRemove, grayscale, is
{asset.collectionIsVerified && <VerifiedIcon className={styles.icon} />}
</Row>
</Column>
{showRemoveButton && !isMobile && (
<Box
marginLeft="16"
className={styles.removeBagRowButton}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
removeAsset([asset])
}}
>
Remove
</Box>
)}
{showRemoveButton && <RemoveButton onClick={handleRemoveClick}>Remove</RemoveButton>}
{(!showRemoveButton || isMobile) && (
<Column flexShrink="0" alignItems="flex-end">
<Box className={styles.bagRowPrice}>
......@@ -212,7 +215,7 @@ const UnavailableAssetsPreview = ({ assets }: UnavailableAssetsPreviewProps) =>
>
{assets.map((asset, index) => (
<Box
key={`preview${index}`}
key={`${asset.address}-${asset.tokenId}`}
as="img"
src={asset.smallImageUrl}
width="32"
......@@ -287,7 +290,7 @@ export const UnavailableAssetsHeaderRow = ({
color="textPrimary"
justifyContent="center"
cursor="pointer"
onClick={() => clearUnavailableAssets()}
onClick={clearUnavailableAssets}
>
<TimedLoader />
<CloseTimerIcon />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment