Commit b30679c9 authored by Callil Capuozzo's avatar Callil Capuozzo Committed by GitHub

style: adjust grid behavior and update collection page styles (#5226)

* Update CollectionNfts.css.ts

* Css details

* Adjust css details

* CSS tweaks

* Adjust colors

* Color tweaks

* update font-size

* Update grid breakpoints

* Refine css grid behavior

* Add comments

* Update outline approach

* Tweaks from review

* Fixes from comments

* fix "sm" breakpoint on item grid

* fix mobile padding alignment and overflow issue

* Update card styles

* Fix overflowing banner dropshadow

* Add requested changes

* Simplify layout for filter chips and buttons

* Add breakpoint sprinkles

* Update Card.css.ts

* Add shared variable

* Address comments

* Address comments

* Clean up card styles
parent 1572410c
...@@ -10,6 +10,7 @@ export const baseActivitySwitcherToggle = style([ ...@@ -10,6 +10,7 @@ export const baseActivitySwitcherToggle = style([
background: 'none', background: 'none',
border: 'none', border: 'none',
cursor: 'pointer', cursor: 'pointer',
marginBottom: '8',
}), }),
{ {
lineHeight: '24px', lineHeight: '24px',
...@@ -32,12 +33,12 @@ export const selectedActivitySwitcherToggle = style([ ...@@ -32,12 +33,12 @@ export const selectedActivitySwitcherToggle = style([
':after': { ':after': {
content: '', content: '',
position: 'absolute', position: 'absolute',
background: vars.color.genieBlue, background: vars.color.textPrimary,
width: '100%', width: '100%',
height: '2px', height: '2px',
left: '0px', left: '0px',
right: '0px', right: '0px',
bottom: '-8px', bottom: '-9px',
}, },
}, },
]) ])
......
...@@ -3,9 +3,16 @@ import { BrowserEvent, ElementName, EventName } from '@uniswap/analytics-events' ...@@ -3,9 +3,16 @@ import { BrowserEvent, ElementName, EventName } from '@uniswap/analytics-events'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Row } from 'nft/components/Flex' import { Row } from 'nft/components/Flex'
import { useIsCollectionLoading } from 'nft/hooks' import { useIsCollectionLoading } from 'nft/hooks'
import styled from 'styled-components/macro'
import * as styles from './ActivitySwitcher.css' import * as styles from './ActivitySwitcher.css'
const BaseActivityContainer = styled(Row)`
border-bottom: 1px solid;
border-color: ${({ theme }) => theme.backgroundInteractive};
margin-right: 12px;
`
export const ActivitySwitcherLoading = new Array(2) export const ActivitySwitcherLoading = new Array(2)
.fill(null) .fill(null)
.map((_, index) => <div className={styles.styledLoading} key={`ActivitySwitcherLoading-key-${index}`} />) .map((_, index) => <div className={styles.styledLoading} key={`ActivitySwitcherLoading-key-${index}`} />)
...@@ -20,7 +27,7 @@ export const ActivitySwitcher = ({ ...@@ -20,7 +27,7 @@ export const ActivitySwitcher = ({
const isLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading) const isLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
return ( return (
<Row gap="24" marginBottom={{ sm: '16', md: '28' }}> <BaseActivityContainer gap="24" marginBottom="16">
{isLoading ? ( {isLoading ? (
ActivitySwitcherLoading ActivitySwitcherLoading
) : ( ) : (
...@@ -47,6 +54,6 @@ export const ActivitySwitcher = ({ ...@@ -47,6 +54,6 @@ export const ActivitySwitcher = ({
</TraceEvent> </TraceEvent>
</> </>
)} )}
</Row> </BaseActivityContainer>
) )
} }
import { style } from '@vanilla-extract/css' import { style } from '@vanilla-extract/css'
import { calc } from '@vanilla-extract/css-utils' import { calc } from '@vanilla-extract/css-utils'
import { sprinkles, themeVars } from 'nft/css/sprinkles.css' import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css'
export const card = style([ export const card = style([
sprinkles({ sprinkles({
overflow: 'hidden', overflow: 'hidden',
borderStyle: 'solid',
borderWidth: '1px',
paddingBottom: '12', paddingBottom: '12',
boxShadow: 'shallow', borderRadius: '16',
}), }),
{ {
boxSizing: 'border-box', boxSizing: 'border-box',
WebkitBoxSizing: 'border-box', WebkitBoxSizing: 'border-box',
boxShadow: vars.color.cardDropShadow,
backgroundColor: themeVars.colors.backgroundSurface,
':after': {
content: '',
position: 'absolute',
top: '0px',
right: ' 0px',
bottom: ' 0px',
left: '0px',
border: ' 1px solid',
borderRadius: '16px',
borderColor: '#5D678524',
pointerEvents: 'none',
},
}, },
]) ])
...@@ -20,20 +32,6 @@ export const loadingBackground = style({ ...@@ -20,20 +32,6 @@ export const loadingBackground = style({
background: `linear-gradient(270deg, ${themeVars.colors.backgroundOutline} 0%, ${themeVars.colors.backgroundSurface} 100%)`, background: `linear-gradient(270deg, ${themeVars.colors.backgroundOutline} 0%, ${themeVars.colors.backgroundSurface} 100%)`,
}) })
export const notSelectedCard = style([
card,
sprinkles({
backgroundColor: 'backgroundSurface',
borderColor: 'backgroundOutline',
borderRadius: '14',
}),
{
':hover': {
backgroundColor: themeVars.colors.stateOverlayHover,
},
},
])
export const cardImageHover = style({ export const cardImageHover = style({
transform: 'scale(1.15)', transform: 'scale(1.15)',
}) })
...@@ -42,13 +40,11 @@ export const selectedCard = style([ ...@@ -42,13 +40,11 @@ export const selectedCard = style([
card, card,
sprinkles({ sprinkles({
background: 'backgroundSurface', background: 'backgroundSurface',
borderColor: 'accentAction',
borderWidth: '3px',
}), }),
{ {
borderRadius: '18px', ':after': {
':hover': { border: '2px solid',
backgroundColor: themeVars.colors.stateOverlayHover, borderColor: vars.color.accentAction,
}, },
}, },
]) ])
......
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
RarityVerifiedIcon, RarityVerifiedIcon,
VerifiedIcon, VerifiedIcon,
} from 'nft/components/icons' } from 'nft/components/icons'
import { body, bodySmall, buttonTextSmall, subhead, subheadSmall } from 'nft/css/common.css' import { body, bodySmall, buttonTextMedium, subhead } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css' import { themeVars } from 'nft/css/sprinkles.css'
import { useIsMobile } from 'nft/hooks' import { useIsMobile } from 'nft/hooks'
import { GenieAsset, Rarity, TokenType, WalletAsset } from 'nft/types' import { GenieAsset, Rarity, TokenType, WalletAsset } from 'nft/types'
...@@ -93,11 +93,17 @@ const baseHref = (asset: GenieAsset | WalletAsset) => { ...@@ -93,11 +93,17 @@ const baseHref = (asset: GenieAsset | WalletAsset) => {
const DetailsLinkContainer = styled.a` const DetailsLinkContainer = styled.a`
display: flex; display: flex;
align-items: center;
flex-shrink: 0; flex-shrink: 0;
text-decoration: none; text-decoration: none;
color: ${({ theme }) => theme.textSecondary}; font-size: 14px;
font-weight: 500;
${OpacityHoverState} border: 1px solid;
color: ${({ theme }) => theme.accentAction};
border-color: ${({ theme }) => theme.accentActionSoft};
padding: 2px 6px;
border-radius: 6px;
${OpacityHoverState};
` `
const SuspiciousIcon = styled(AlertTriangle)` const SuspiciousIcon = styled(AlertTriangle)`
...@@ -211,9 +217,7 @@ const Container = ({ ...@@ -211,9 +217,7 @@ const Container = ({
position="relative" position="relative"
ref={assetRef} ref={assetRef}
borderRadius={BORDER_RADIUS} borderRadius={BORDER_RADIUS}
borderBottomLeftRadius={BORDER_RADIUS} className={selected ? styles.selectedCard : styles.card}
borderBottomRightRadius={BORDER_RADIUS}
className={selected ? styles.selectedCard : styles.notSelectedCard}
draggable={false} draggable={false}
onMouseEnter={() => toggleHovered()} onMouseEnter={() => toggleHovered()}
onMouseLeave={() => toggleHovered()} onMouseLeave={() => toggleHovered()}
...@@ -251,7 +255,7 @@ const Image = () => { ...@@ -251,7 +255,7 @@ const Image = () => {
width="full" width="full"
style={{ style={{
aspectRatio: '1', aspectRatio: '1',
transition: 'transform 0.4s ease 0s', transition: 'transform 0.25s ease 0s',
}} }}
src={asset.imageUrl || asset.smallImageUrl} src={asset.imageUrl || asset.smallImageUrl}
objectFit="contain" objectFit="contain"
...@@ -297,7 +301,7 @@ const Video = ({ shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => { ...@@ -297,7 +301,7 @@ const Video = ({ shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => {
width="full" width="full"
style={{ style={{
aspectRatio: '1', aspectRatio: '1',
transition: 'transform 0.4s ease 0s', transition: 'transform 0.25s ease 0s',
willChange: 'transform', willChange: 'transform',
}} }}
src={asset.imageUrl || asset.smallImageUrl} src={asset.imageUrl || asset.smallImageUrl}
...@@ -514,7 +518,7 @@ const ProfileNftDetails = ({ asset, hideDetails }: ProfileNftDetailsProps) => { ...@@ -514,7 +518,7 @@ const ProfileNftDetails = ({ asset, hideDetails }: ProfileNftDetailsProps) => {
</PrimaryRow> </PrimaryRow>
<Row justifyItems="flex-start"> <Row justifyItems="flex-start">
<TruncatedTextRow <TruncatedTextRow
className={subheadSmall} className={body}
style={{ style={{
color: themeVars.colors.textPrimary, color: themeVars.colors.textPrimary,
}} }}
...@@ -524,7 +528,7 @@ const ProfileNftDetails = ({ asset, hideDetails }: ProfileNftDetailsProps) => { ...@@ -524,7 +528,7 @@ const ProfileNftDetails = ({ asset, hideDetails }: ProfileNftDetailsProps) => {
{asset.susFlag && <Suspicious />} {asset.susFlag && <Suspicious />}
</Row> </Row>
{shouldShowUserListedPrice && ( {shouldShowUserListedPrice && (
<TruncatedTextRow className={subhead} style={{ color: themeVars.colors.textPrimary }}> <TruncatedTextRow className={buttonTextMedium} style={{ color: themeVars.colors.textPrimary }}>
{`${floorFormatter(asset.floor_sell_order_price)} ETH`} {`${floorFormatter(asset.floor_sell_order_price)} ETH`}
</TruncatedTextRow> </TruncatedTextRow>
)} )}
...@@ -546,15 +550,7 @@ const PrimaryDetails = ({ children }: { children: ReactNode }) => ( ...@@ -546,15 +550,7 @@ const PrimaryDetails = ({ children }: { children: ReactNode }) => (
const PrimaryInfo = ({ children }: { children: ReactNode }) => { const PrimaryInfo = ({ children }: { children: ReactNode }) => {
return ( return (
<Box <Box overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" className={body}>
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
color="textPrimary"
fontWeight="medium"
fontSize="14"
style={{ lineHeight: '20px' }}
>
{children} {children}
</Box> </Box>
) )
...@@ -579,9 +575,8 @@ const SecondaryInfo = ({ children }: { children: ReactNode }) => { ...@@ -579,9 +575,8 @@ const SecondaryInfo = ({ children }: { children: ReactNode }) => {
overflow="hidden" overflow="hidden"
whiteSpace="nowrap" whiteSpace="nowrap"
textOverflow="ellipsis" textOverflow="ellipsis"
fontSize="16"
fontWeight="medium"
style={{ lineHeight: '20px' }} style={{ lineHeight: '20px' }}
className={subhead}
> >
{children} {children}
</Box> </Box>
...@@ -649,7 +644,7 @@ const DetailsLink = () => { ...@@ -649,7 +644,7 @@ const DetailsLink = () => {
e.stopPropagation() e.stopPropagation()
}} }}
> >
<Box className={buttonTextSmall}>Details</Box> <Box>Details</Box>
</DetailsLinkContainer> </DetailsLinkContainer>
) )
} }
...@@ -747,7 +742,6 @@ const NoContentContainer = () => ( ...@@ -747,7 +742,6 @@ const NoContentContainer = () => (
left="1/2" left="1/2"
top="1/2" top="1/2"
style={{ transform: 'translate3d(-50%, -50%, 0)' }} style={{ transform: 'translate3d(-50%, -50%, 0)' }}
fontWeight="normal"
color="gray500" color="gray500"
className={body} className={body}
> >
......
import { style } from '@vanilla-extract/css' import { style } from '@vanilla-extract/css'
import { sprinkles } from '../../css/sprinkles.css' import { breakpoints, sprinkles } from '../../css/sprinkles.css'
export const assetList = style([ export const assetList = style([
sprinkles({ sprinkles({
display: 'grid', display: 'grid',
gap: { sm: '8', md: '12', lg: '20' }, gap: { sm: '8', md: '8', lg: '12', xl: '16', xxl: '20', xxxl: '20' },
}), }),
{ {
paddingLeft: 14, //This treatment of the grid still uses minmax, but enforces an amount of grid items per breakpoint. This means that when the bag and filter panels appear, we no longer get layout thrash and have a consistent animation as the width changes. It uses calc() and subtracts the grid gap to ensure the min size will always fit without wrapping.
paddingRight: 14, gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/2 - 8px), 1fr) )',
gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr) )',
'@media': { '@media': {
'screen and (min-width: 708px)': { [`screen and (min-width: ${breakpoints.md}px)`]: {
gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr) )', gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/3 - 8px), 1fr) )',
}, },
'screen and (min-width: 1185px)': { [`screen and (min-width: ${breakpoints.lg}px)`]: {
gridTemplateColumns: 'repeat(auto-fill, minmax(1fr, 280px) )', gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/3 - 12px), 1fr) )',
},
[`screen and (min-width: ${breakpoints.xl}px)`]: {
gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/4 - 16px), 1fr) )',
},
[`screen and (min-width: ${breakpoints.xxl}px)`]: {
gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/5 - 20px), 1fr) )',
},
[`screen and (min-width: ${breakpoints.xxxl}px)`]: {
gridTemplateColumns: 'repeat(auto-fill, minmax(calc(100%/7 - 20px), 1fr) )',
}, },
}, },
}, },
]) ])
//Using negative margin and overflowing the width but 2*16px so that the edges of this area always properly clip the softer, wider shadow on the cards
export const actionBarContainer = style([{ marginLeft: '-16px', width: 'calc(100% + 32px)' }])
...@@ -110,7 +110,6 @@ const SweepButton = styled.div<{ toggled: boolean; disabled?: boolean }>` ...@@ -110,7 +110,6 @@ const SweepButton = styled.div<{ toggled: boolean; disabled?: boolean }>`
border: none; border: none;
border-radius: 12px; border-radius: 12px;
padding: 12px 18px 12px 12px; padding: 12px 18px 12px 12px;
margin-right: 14px;
cursor: ${({ disabled }) => (disabled ? 'auto' : 'pointer')}; cursor: ${({ disabled }) => (disabled ? 'auto' : 'pointer')};
color: ${({ toggled, disabled, theme }) => (toggled && !disabled ? theme.accentTextLightPrimary : theme.textPrimary)}; color: ${({ toggled, disabled, theme }) => (toggled && !disabled ? theme.accentTextLightPrimary : theme.textPrimary)};
background: ${({ theme, toggled, disabled }) => background: ${({ theme, toggled, disabled }) =>
...@@ -434,116 +433,118 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie ...@@ -434,116 +433,118 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
return ( return (
<> <>
<AnimatedBox position="sticky" top="72" width="full" zIndex="3" marginBottom={{ sm: '8', md: '20' }}> <AnimatedBox
<Box backgroundColor="backgroundBackdrop"
backgroundColor="backgroundBackdrop" position="sticky"
width="full" top="72"
paddingTop={{ sm: '12', md: '16' }} width="full"
paddingBottom={{ sm: '12', md: '16' }} zIndex="3"
> marginBottom={{ sm: '8', md: '20' }}
<ActionsContainer> padding="16"
<ActionsSubContainer> className={styles.actionBarContainer}
<TraceEvent >
events={[BrowserEvent.onClick]} <ActionsContainer>
element={ElementName.NFT_FILTER_BUTTON} <ActionsSubContainer>
name={EventName.NFT_FILTER_OPENED} <TraceEvent
shouldLogImpression={!isFiltersExpanded} events={[BrowserEvent.onClick]}
properties={{ collection_address: contractAddress, chain_id: chainId }} element={ElementName.NFT_FILTER_BUTTON}
> name={EventName.NFT_FILTER_OPENED}
<FilterButton shouldLogImpression={!isFiltersExpanded}
isMobile={isMobile} properties={{ collection_address: contractAddress, chain_id: chainId }}
isFiltersExpanded={isFiltersExpanded} >
collectionCount={collectionAssets?.[0]?.totalCount ?? 0} <FilterButton
onClick={() => setFiltersExpanded(!isFiltersExpanded)} isMobile={isMobile}
/> isFiltersExpanded={isFiltersExpanded}
</TraceEvent> collectionCount={collectionAssets?.[0]?.totalCount ?? 0}
<SortDropdownContainer isFiltersExpanded={isFiltersExpanded}> onClick={() => setFiltersExpanded(!isFiltersExpanded)}
<SortDropdown dropDownOptions={sortDropDownOptions} />
</SortDropdownContainer>
<CollectionSearch />
</ActionsSubContainer>
{!hasErc1155s ? (
<SweepButton
toggled={sweepIsOpen}
disabled={hasErc1155s}
className={buttonTextMedium}
onClick={() => {
if (hasErc1155s) return
if (!sweepIsOpen) {
scrollToTop()
if (!bagExpanded && !isMobile) toggleBag()
}
setSweepOpen(!sweepIsOpen)
}}
>
<SweepIcon viewBox="0 0 24 24" width="20px" height="20px" />
<SweepText fontWeight={600} color="currentColor" lineHeight="20px">
Sweep
</SweepText>
</SweepButton>
) : null}
</ActionsContainer>
{sweepIsOpen && (
<Sweep contractAddress={contractAddress} minPrice={debouncedMinPrice} maxPrice={debouncedMaxPrice} />
)}
<Row
paddingTop={!!markets.length || !!traits.length || minMaxPriceChipText ? '12' : '0'}
gap="8"
flexWrap="wrap"
>
{markets.map((market) => (
<TraitChip
key={market}
value={
<MarketNameWrapper>
<MarketplaceLogo src={`/nft/svgs/marketplaces/${market.toLowerCase()}.svg`} />
{MARKETPLACE_ITEMS[market as keyof typeof MARKETPLACE_ITEMS]}
</MarketNameWrapper>
}
onClick={() => {
scrollToTop()
removeMarket(market)
}}
/>
))}
{traits.map((trait) => (
<TraitChip
key={trait.trait_value}
value={
trait.trait_type === 'Number of traits'
? `${trait.trait_value} trait${pluralize(Number(trait.trait_value))}`
: `${trait.trait_type}: ${trait.trait_value}`
}
onClick={() => {
scrollToTop()
removeTrait(trait)
}}
/>
))}
{minMaxPriceChipText && (
<TraitChip
value={minMaxPriceChipText}
onClick={() => {
scrollToTop()
setMin('')
setMax('')
setPrevMinMax([0, 100])
}}
/> />
)} </TraceEvent>
{!!traits.length || !!markets.length || minMaxPriceChipText ? ( <SortDropdownContainer isFiltersExpanded={isFiltersExpanded}>
<ClearAllButton <SortDropdown dropDownOptions={sortDropDownOptions} />
onClick={() => { </SortDropdownContainer>
reset() <CollectionSearch />
setPrevMinMax([0, 100]) </ActionsSubContainer>
{!hasErc1155s ? (
<SweepButton
toggled={sweepIsOpen}
disabled={hasErc1155s}
className={buttonTextMedium}
onClick={() => {
if (hasErc1155s) return
if (!sweepIsOpen) {
scrollToTop() scrollToTop()
}} if (!bagExpanded && !isMobile) toggleBag()
> }
Clear All setSweepOpen(!sweepIsOpen)
</ClearAllButton> }}
) : null} >
</Row> <SweepIcon viewBox="0 0 24 24" width="20px" height="20px" />
</Box> <SweepText fontWeight={600} color="currentColor" lineHeight="20px">
Sweep
</SweepText>
</SweepButton>
) : null}
</ActionsContainer>
{sweepIsOpen && (
<Sweep contractAddress={contractAddress} minPrice={debouncedMinPrice} maxPrice={debouncedMaxPrice} />
)}
<Row
paddingTop={!!markets.length || !!traits.length || minMaxPriceChipText ? '12' : '0'}
gap="8"
flexWrap="wrap"
>
{markets.map((market) => (
<TraitChip
key={market}
value={
<MarketNameWrapper>
<MarketplaceLogo src={`/nft/svgs/marketplaces/${market.toLowerCase()}.svg`} />
{MARKETPLACE_ITEMS[market as keyof typeof MARKETPLACE_ITEMS]}
</MarketNameWrapper>
}
onClick={() => {
scrollToTop()
removeMarket(market)
}}
/>
))}
{traits.map((trait) => (
<TraitChip
key={trait.trait_value}
value={
trait.trait_type === 'Number of traits'
? `${trait.trait_value} trait${pluralize(Number(trait.trait_value))}`
: `${trait.trait_type}: ${trait.trait_value}`
}
onClick={() => {
scrollToTop()
removeTrait(trait)
}}
/>
))}
{minMaxPriceChipText && (
<TraitChip
value={minMaxPriceChipText}
onClick={() => {
scrollToTop()
setMin('')
setMax('')
setPrevMinMax([0, 100])
}}
/>
)}
{!!traits.length || !!markets.length || minMaxPriceChipText ? (
<ClearAllButton
onClick={() => {
reset()
setPrevMinMax([0, 100])
scrollToTop()
}}
>
Clear All
</ClearAllButton>
) : null}
</Row>
</AnimatedBox> </AnimatedBox>
<InfiniteScroll <InfiniteScroll
next={() => loadNext(ASSET_PAGE_SIZE)} next={() => loadNext(ASSET_PAGE_SIZE)}
......
import { globalStyle, style } from '@vanilla-extract/css' import { globalStyle, style } from '@vanilla-extract/css'
import { bodySmall, buttonTextSmall, headlineSmall } from 'nft/css/common.css' import { bodySmall, headlineSmall, subheadSmall } from 'nft/css/common.css'
import { loadingAsset, loadingBlock } from 'nft/css/loading.css' import { loadingAsset, loadingBlock } from 'nft/css/loading.css'
import { breakpoints, sprinkles, themeVars } from '../../css/sprinkles.css' import { breakpoints, sprinkles, themeVars, vars } from '../../css/sprinkles.css'
export const statsText = style([ export const statsText = style([
sprinkles({ sprinkles({
...@@ -34,6 +34,7 @@ export const collectionImage = style([ ...@@ -34,6 +34,7 @@ export const collectionImage = style([
height: '143px', height: '143px',
verticalAlign: 'top', verticalAlign: 'top',
top: '-118px', top: '-118px',
boxShadow: vars.color.cardDropShadow,
'@media': { '@media': {
[`(max-width: ${breakpoints.sm - 1}px)`]: { [`(max-width: ${breakpoints.sm - 1}px)`]: {
width: '60px', width: '60px',
...@@ -94,11 +95,10 @@ export const descriptionOpen = style([ ...@@ -94,11 +95,10 @@ export const descriptionOpen = style([
]) ])
export const readMore = style([ export const readMore = style([
bodySmall,
{ {
verticalAlign: 'top', verticalAlign: 'top',
lineHeight: '20px',
}, },
buttonTextSmall,
sprinkles({ sprinkles({
color: 'textSecondary', color: 'textSecondary',
cursor: 'pointer', cursor: 'pointer',
...@@ -107,9 +107,8 @@ export const readMore = style([ ...@@ -107,9 +107,8 @@ export const readMore = style([
]) ])
export const statsLabel = style([ export const statsLabel = style([
bodySmall, subheadSmall,
sprinkles({ sprinkles({
fontWeight: 'normal',
color: 'textSecondary', color: 'textSecondary',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
}), }),
...@@ -120,9 +119,6 @@ export const statsLabel = style([ ...@@ -120,9 +119,6 @@ export const statsLabel = style([
export const statsValue = style([ export const statsValue = style([
headlineSmall, headlineSmall,
sprinkles({
fontWeight: 'medium',
}),
{ {
lineHeight: '24px', lineHeight: '24px',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
......
...@@ -287,7 +287,7 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob ...@@ -287,7 +287,7 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob
const arrow = stats?.stats?.one_day_floor_change ? getDeltaArrow(stats.stats.one_day_floor_change) : undefined const arrow = stats?.stats?.one_day_floor_change ? getDeltaArrow(stats.stats.one_day_floor_change) : undefined
return ( return (
<Row gap={{ sm: '36', md: '60' }} {...props}> <Row gap={{ sm: '24', md: '36', lg: '48', xl: '60' }} {...props}>
{isCollectionStatsLoading ? ( {isCollectionStatsLoading ? (
statsLoadingSkeleton(isMobile ?? false) statsLoadingSkeleton(isMobile ?? false)
) : ( ) : (
...@@ -315,7 +315,6 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob ...@@ -315,7 +315,6 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob
{totalSupplyStr} {totalSupplyStr}
</StatsItem> </StatsItem>
) : null} ) : null}
{Boolean(uniqueOwnersPercentage && stats.standard !== TokenType.ERC1155) ? ( {Boolean(uniqueOwnersPercentage && stats.standard !== TokenType.ERC1155) ? (
<StatsItem label="Unique owners" shouldHide={isMobile ?? false}> <StatsItem label="Unique owners" shouldHide={isMobile ?? false}>
{uniqueOwnersPercentage}% {uniqueOwnersPercentage}%
......
...@@ -3,7 +3,7 @@ import { loadingAsset } from 'nft/css/loading.css' ...@@ -3,7 +3,7 @@ import { loadingAsset } from 'nft/css/loading.css'
import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css' import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css'
export const filterButton = sprinkles({ export const filterButton = sprinkles({
backgroundColor: 'accentAction', backgroundColor: 'textTertiary',
color: 'textPrimary', color: 'textPrimary',
}) })
......
...@@ -27,7 +27,6 @@ export const FilterButton = ({ ...@@ -27,7 +27,6 @@ export const FilterButton = ({
position="relative" position="relative"
onClick={onClick} onClick={onClick}
padding="12" padding="12"
marginLeft="14"
width={isMobile ? '44' : 'auto'} width={isMobile ? '44' : 'auto'}
height="44" height="44"
whiteSpace="nowrap" whiteSpace="nowrap"
...@@ -36,12 +35,10 @@ export const FilterButton = ({ ...@@ -36,12 +35,10 @@ export const FilterButton = ({
<FilterIcon /> <FilterIcon />
{!isMobile ? ( {!isMobile ? (
<> <>
{!isFiltersExpanded && ( <Box className={buttonTextMedium}>
<Box className={buttonTextMedium}> {' '}
{' '} Filter • {putCommas(collectionCount)} result{pluralize(collectionCount)}
Filter • {putCommas(collectionCount)} result{pluralize(collectionCount)} </Box>
</Box>
)}
</> </>
) : null} ) : null}
</Box> </Box>
......
...@@ -72,8 +72,8 @@ export const detailsOpen = style([ ...@@ -72,8 +72,8 @@ export const detailsOpen = style([
borderTop, borderTop,
sprinkles({ sprinkles({
overflow: 'hidden', overflow: 'hidden',
marginTop: '8', marginTop: '2',
marginBottom: '8', marginBottom: '2',
}), }),
]) ])
......
...@@ -14,11 +14,15 @@ import { ThemedText } from 'theme' ...@@ -14,11 +14,15 @@ import { ThemedText } from 'theme'
const SweepContainer = styled.div` const SweepContainer = styled.div`
display: flex; display: flex;
gap: 60px; gap: 60px;
margin-top: 20px; margin-top: 12px;
padding: 16px; padding: 16px;
border-radius: 12px; border-radius: 12px;
background-color: ${({ theme }) => theme.backgroundModule}; background-color: ${({ theme }) => theme.backgroundSurface};
justify-content: space-between; justify-content: space-between;
background: linear-gradient(${({ theme }) => theme.backgroundSurface}, ${({ theme }) => theme.backgroundSurface})
padding-box,
linear-gradient(to right, #4673fa, #9646fa) border-box;
border: 2px solid transparent;
` `
const StyledSlider = styled(Slider)` const StyledSlider = styled(Slider)`
...@@ -66,7 +70,7 @@ const InputContainer = styled.input` ...@@ -66,7 +70,7 @@ const InputContainer = styled.input`
background: none; background: none;
border-radius: 8px; border-radius: 8px;
padding: 6px 8px; padding: 6px 8px;
font-size: 14px; font-size: 16px;
font-weight: 400px; font-weight: 400px;
line-height: 20px; line-height: 20px;
...@@ -336,9 +340,9 @@ export const Sweep = ({ contractAddress, minPrice, maxPrice }: SweepProps) => { ...@@ -336,9 +340,9 @@ export const Sweep = ({ contractAddress, minPrice, maxPrice }: SweepProps) => {
<SweepContainer> <SweepContainer>
<SweepLeftmostContainer> <SweepLeftmostContainer>
<SweepHeaderContainer> <SweepHeaderContainer>
<ThemedText.SubHeaderSmall color="textPrimary" lineHeight="20px" paddingTop="6px" paddingBottom="6px"> <ThemedText.SubHeader color="textPrimary" lineHeight="20px" paddingTop="6px" paddingBottom="6px">
Sweep Sweep
</ThemedText.SubHeaderSmall> </ThemedText.SubHeader>
</SweepHeaderContainer> </SweepHeaderContainer>
<SweepSubContainer> <SweepSubContainer>
<StyledSlider <StyledSlider
...@@ -356,15 +360,16 @@ export const Sweep = ({ contractAddress, minPrice, maxPrice }: SweepProps) => { ...@@ -356,15 +360,16 @@ export const Sweep = ({ contractAddress, minPrice, maxPrice }: SweepProps) => {
top: '3px', top: '3px',
width: '12px', width: '12px',
height: '20px', height: '20px',
backgroundColor: `${theme.textPrimary}`, backgroundColor: `#4673FA`, //This is a custom color to align with the gradient on sweep - we may want to systematize it eventually
borderRadius: '4px', borderRadius: '4px',
border: 'none', border: 'none',
opacity: '1',
boxShadow: `${theme.shallowShadow.slice(0, -1)}`, boxShadow: `${theme.shallowShadow.slice(0, -1)}`,
}} }}
railStyle={{ railStyle={{
top: '3px', top: '3px',
height: '8px', height: '8px',
backgroundColor: `${theme.accentActionSoft}`, backgroundColor: `${theme.backgroundInteractive}`,
}} }}
onChange={handleSliderChange} onChange={handleSliderChange}
/> />
......
...@@ -53,7 +53,6 @@ export const SortDropdown = ({ ...@@ -53,7 +53,6 @@ export const SortDropdown = ({
return ( return (
<Box <Box
ref={ref} ref={ref}
transition="250"
borderRadius="12" borderRadius="12"
borderBottomLeftRadius={isOpen ? '0' : undefined} borderBottomLeftRadius={isOpen ? '0' : undefined}
borderBottomRightRadius={isOpen ? '0' : undefined} borderBottomRightRadius={isOpen ? '0' : undefined}
......
...@@ -266,7 +266,7 @@ export const ArrowsIcon = () => ( ...@@ -266,7 +266,7 @@ export const ArrowsIcon = () => (
) )
export const ReversedArrowsIcon = () => ( export const ReversedArrowsIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="20" height="20" viewBox="0 3 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path
d="M19.4834 5.71191C19.0879 5.29883 18.4727 5.30762 18.0859 5.71191L13.6562 10.2471C13.4805 10.4229 13.3662 10.6953 13.3662 10.9326C13.3662 11.4863 13.7529 11.8643 14.2979 11.8643C14.5615 11.8643 14.7725 11.7764 14.9482 11.5918L16.7588 9.71094L17.9189 8.375L17.8486 10.2383L17.8486 21.6465C17.8486 22.1914 18.2441 22.5869 18.7891 22.5869C19.334 22.5869 19.7207 22.1914 19.7207 21.6465L19.7207 10.2383L19.6592 8.375L20.8105 9.71094L22.6211 11.5918C22.7969 11.7764 23.0166 11.8643 23.2803 11.8643C23.8164 11.8643 24.2031 11.4863 24.2031 10.9326C24.2031 10.6953 24.0889 10.4229 23.9131 10.2471L19.4834 5.71191ZM7.84668 22.2793C8.24218 22.6924 8.85742 22.6836 9.24414 22.2793L13.6738 17.7529C13.8496 17.5684 13.9639 17.2959 13.9639 17.0586C13.9639 16.5137 13.5771 16.1357 13.0322 16.1357C12.7773 16.1357 12.5576 16.2236 12.3818 16.3994L10.5713 18.2803L9.41992 19.6162L9.48144 17.7529L9.48144 6.34473C9.48144 5.80859 9.08594 5.4043 8.54101 5.4043C8.00488 5.4043 7.60937 5.80859 7.60937 6.34473L7.60937 17.7529L7.6709 19.6162L6.51953 18.2803L4.70898 16.3994C4.5332 16.2236 4.31347 16.1357 4.05859 16.1357C3.51367 16.1357 3.12695 16.5137 3.12695 17.0586C3.12695 17.2959 3.24121 17.5684 3.41699 17.7529L7.84668 22.2793Z" d="M19.4834 5.71191C19.0879 5.29883 18.4727 5.30762 18.0859 5.71191L13.6562 10.2471C13.4805 10.4229 13.3662 10.6953 13.3662 10.9326C13.3662 11.4863 13.7529 11.8643 14.2979 11.8643C14.5615 11.8643 14.7725 11.7764 14.9482 11.5918L16.7588 9.71094L17.9189 8.375L17.8486 10.2383L17.8486 21.6465C17.8486 22.1914 18.2441 22.5869 18.7891 22.5869C19.334 22.5869 19.7207 22.1914 19.7207 21.6465L19.7207 10.2383L19.6592 8.375L20.8105 9.71094L22.6211 11.5918C22.7969 11.7764 23.0166 11.8643 23.2803 11.8643C23.8164 11.8643 24.2031 11.4863 24.2031 10.9326C24.2031 10.6953 24.0889 10.4229 23.9131 10.2471L19.4834 5.71191ZM7.84668 22.2793C8.24218 22.6924 8.85742 22.6836 9.24414 22.2793L13.6738 17.7529C13.8496 17.5684 13.9639 17.2959 13.9639 17.0586C13.9639 16.5137 13.5771 16.1357 13.0322 16.1357C12.7773 16.1357 12.5576 16.2236 12.3818 16.3994L10.5713 18.2803L9.41992 19.6162L9.48144 17.7529L9.48144 6.34473C9.48144 5.80859 9.08594 5.4043 8.54101 5.4043C8.00488 5.4043 7.60937 5.80859 7.60937 6.34473L7.60937 17.7529L7.6709 19.6162L6.51953 18.2803L4.70898 16.3994C4.5332 16.2236 4.31347 16.1357 4.05859 16.1357C3.51367 16.1357 3.12695 16.5137 3.12695 17.0586C3.12695 17.2959 3.24121 17.5684 3.41699 17.7529L7.84668 22.2793Z"
fill="currentColor" fill="currentColor"
......
...@@ -21,9 +21,9 @@ export const column = sprinkles({ ...@@ -21,9 +21,9 @@ export const column = sprinkles({
}) })
// TYPOGRAPHY // TYPOGRAPHY
export const headlineLarge = sprinkles({ fontWeight: 'medium', fontSize: '36', lineHeight: '44' }) export const headlineLarge = sprinkles({ fontWeight: 'semibold', fontSize: '36', lineHeight: '44' })
export const headlineMedium = sprinkles({ fontWeight: 'medium', fontSize: '28', lineHeight: '36' }) export const headlineMedium = sprinkles({ fontWeight: 'semibold', fontSize: '28', lineHeight: '36' })
export const headlineSmall = sprinkles({ fontWeight: 'medium', fontSize: '20', lineHeight: '28' }) export const headlineSmall = sprinkles({ fontWeight: 'semibold', fontSize: '20', lineHeight: '28' })
export const subhead = sprinkles({ fontWeight: 'medium', fontSize: '16', lineHeight: '24' }) export const subhead = sprinkles({ fontWeight: 'medium', fontSize: '16', lineHeight: '24' })
export const subheadSmall = sprinkles({ fontWeight: 'medium', fontSize: '14', lineHeight: '14' }) export const subheadSmall = sprinkles({ fontWeight: 'medium', fontSize: '14', lineHeight: '14' })
......
...@@ -154,6 +154,7 @@ export const vars = createGlobalTheme(':root', { ...@@ -154,6 +154,7 @@ export const vars = createGlobalTheme(':root', {
fallbackGradient: 'linear-gradient(270deg, #D1D5DB 0%, #F6F6F6 100%)', fallbackGradient: 'linear-gradient(270deg, #D1D5DB 0%, #F6F6F6 100%)',
loadingBackground: '#24272e', loadingBackground: '#24272e',
dropShadow: '0px 4px 16px rgba(70, 115, 250, 0.4)', dropShadow: '0px 4px 16px rgba(70, 115, 250, 0.4)',
cardDropShadow: 'rgba(0, 0, 0, 10%) 0px 4px 12px',
green: '#209853', green: '#209853',
orange: '#FA2C38', orange: '#FA2C38',
black: 'black', black: 'black',
......
...@@ -72,8 +72,8 @@ export const ScreenBreakpointsPaddings = css` ...@@ -72,8 +72,8 @@ export const ScreenBreakpointsPaddings = css`
} }
@media screen and (max-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) { @media screen and (max-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) {
padding-left: 40px; padding-left: 26px;
padding-right: 40px; padding-right: 26px;
} }
@media screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) { @media screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
......
...@@ -21,13 +21,13 @@ import * as styles from 'nft/pages/collection/index.css' ...@@ -21,13 +21,13 @@ import * as styles from 'nft/pages/collection/index.css'
import { GenieCollection } from 'nft/types' import { GenieCollection } from 'nft/types'
import { Suspense, useEffect } from 'react' import { Suspense, useEffect } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom' import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { useSpring } from 'react-spring' import { easings, useSpring } from 'react-spring'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
const FILTER_WIDTH = 332 const FILTER_WIDTH = 332
const BAG_WIDTH = 324 const BAG_WIDTH = 324
export const COLLECTION_BANNER_HEIGHT = 276 export const COLLECTION_BANNER_HEIGHT = 288
export const CollectionBannerLoading = () => <Box height="full" width="full" className={styles.loadingBanner} /> export const CollectionBannerLoading = () => <Box height="full" width="full" className={styles.loadingBanner} />
...@@ -41,11 +41,12 @@ const MobileFilterHeader = styled(Row)` ...@@ -41,11 +41,12 @@ const MobileFilterHeader = styled(Row)`
` `
// Sticky navbar on light mode looks incorrect because the box shadows from assets overlap the the edges of the navbar. // Sticky navbar on light mode looks incorrect because the box shadows from assets overlap the the edges of the navbar.
// As a result it needs 14px padding on either side. These paddings are offset by 14px to account for this // As a result it needs 16px padding on either side. These paddings are offset by 16px to account for this. Please see CollectionNFTs.css.ts for the additional sizing context.
// See breakpoint values in ScreenBreakpointsPaddings above - they must match
const CollectionDisplaySection = styled(Row)` const CollectionDisplaySection = styled(Row)`
@media screen and (min-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) { @media screen and (min-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) {
padding-left: 34px; padding-left: 48px;
padding-right: 34px; padding-right: 48px;
} }
@media screen and (max-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) { @media screen and (max-width: ${MAX_WIDTH_MEDIA_BREAKPOINT}) {
...@@ -54,12 +55,13 @@ const CollectionDisplaySection = styled(Row)` ...@@ -54,12 +55,13 @@ const CollectionDisplaySection = styled(Row)`
} }
@media screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) { @media screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
padding-left: 4px; padding-left: 20px;
padding-right: 4px; padding-right: 20px;
} }
@media screen and (max-width: ${MOBILE_MEDIA_BREAKPOINT}) { @media screen and (max-width: ${MOBILE_MEDIA_BREAKPOINT}) {
padding-left: 16px; padding-left: 16px;
padding-right: 16px;
} }
align-items: flex-start; align-items: flex-start;
position: relative; position: relative;
...@@ -101,6 +103,10 @@ const Collection = () => { ...@@ -101,6 +103,10 @@ const Collection = () => {
: isBagExpanded : isBagExpanded
? BAG_WIDTH ? BAG_WIDTH
: 0, : 0,
config: {
duration: 250,
easing: easings.easeOutSine,
},
}) })
useEffect(() => { useEffect(() => {
...@@ -127,7 +133,6 @@ const Collection = () => { ...@@ -127,7 +133,6 @@ const Collection = () => {
<Column width="full"> <Column width="full">
{contractAddress ? ( {contractAddress ? (
<> <>
{' '}
<Box width="full" height={`${COLLECTION_BANNER_HEIGHT}`}> <Box width="full" height={`${COLLECTION_BANNER_HEIGHT}`}>
<Box <Box
as={collectionStats?.bannerImageUrl ? 'img' : 'div'} as={collectionStats?.bannerImageUrl ? 'img' : 'div'}
......
...@@ -15,7 +15,7 @@ export const darkTheme: Theme = { ...@@ -15,7 +15,7 @@ export const darkTheme: Theme = {
backgroundFloating: '0000000C', backgroundFloating: '0000000C',
backgroundInteractive: vars.color.gray700, backgroundInteractive: vars.color.gray700,
backgroundModule: vars.color.gray800, backgroundModule: vars.color.gray800,
backgroundOutline: `rgba(153,161,189,0.24)`, backgroundOutline: vars.color.backgroundInteractive,
backgroundSurface: vars.color.gray900, backgroundSurface: vars.color.gray900,
backgroundBackdrop: '#000', backgroundBackdrop: '#000',
......
...@@ -5,14 +5,14 @@ export const lightTheme: Theme = { ...@@ -5,14 +5,14 @@ export const lightTheme: Theme = {
accentFailure: vars.color.red400, accentFailure: vars.color.red400,
accentFailureSoft: 'rgba(250, 43, 57, 0.12)', accentFailureSoft: 'rgba(250, 43, 57, 0.12)',
accentAction: vars.color.pink400, accentAction: vars.color.pink400,
accentActionSoft: 'rgba(251, 17, 142, 0.12)', accentActionSoft: vars.color.accentActionSoft,
explicitWhite: '#FFFFFF', explicitWhite: '#FFFFFF',
backgroundFloating: '#00000000', backgroundFloating: '#00000000',
backgroundInteractive: vars.color.gray100, backgroundInteractive: vars.color.gray50,
backgroundModule: vars.color.gray50, backgroundModule: vars.color.gray50,
backgroundOutline: `rgba(94,104,135,0.24)`, backgroundOutline: vars.color.gray100,
backgroundSurface: '#FFFFFF', backgroundSurface: '#FFFFFF',
backgroundBackdrop: '#FFF', backgroundBackdrop: '#FFF',
......
...@@ -247,7 +247,7 @@ export interface Palette { ...@@ -247,7 +247,7 @@ export interface Palette {
} }
export const colorsLight: Palette = { export const colorsLight: Palette = {
userThemeColor: colors.magentaVibrant, userThemeColor: colors.pink400,
background: '#faf9fa', //INTENTIONALLY OFF THEME TO GIVE WHITE BG A SOFTER VISUAL background: '#faf9fa', //INTENTIONALLY OFF THEME TO GIVE WHITE BG A SOFTER VISUAL
backgroundBackdrop: colors.white, backgroundBackdrop: colors.white,
...@@ -255,7 +255,7 @@ export const colorsLight: Palette = { ...@@ -255,7 +255,7 @@ export const colorsLight: Palette = {
backgroundModule: colors.gray50, backgroundModule: colors.gray50,
backgroundInteractive: colors.gray100, backgroundInteractive: colors.gray100,
backgroundFloating: opacify(8, colors.gray700), backgroundFloating: opacify(8, colors.gray700),
backgroundOutline: colors.gray150, backgroundOutline: colors.gray100,
backgroundScrim: opacify(60, colors.gray900), backgroundScrim: opacify(60, colors.gray900),
backgroundScrolledSurface: opacify(72, colors.white), backgroundScrolledSurface: opacify(72, colors.white),
......
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