Commit 155bf2e8 authored by Jack Short's avatar Jack Short Committed by GitHub

style: updated collection cards (#5047)

parent 6e282a6d
...@@ -7,6 +7,8 @@ export const card = style([ ...@@ -7,6 +7,8 @@ export const card = style([
overflow: 'hidden', overflow: 'hidden',
borderStyle: 'solid', borderStyle: 'solid',
borderWidth: '1px', borderWidth: '1px',
paddingBottom: '12',
boxShadow: 'shallow',
}), }),
{ {
boxSizing: 'border-box', boxSizing: 'border-box',
...@@ -20,9 +22,6 @@ export const card = style([ ...@@ -20,9 +22,6 @@ export const card = style([
}, },
}, },
}, },
':hover': {
boxShadow: themeVars.shadows.deep,
},
}, },
]) ])
...@@ -34,8 +33,13 @@ export const notSelectedCard = style([ ...@@ -34,8 +33,13 @@ export const notSelectedCard = style([
card, card,
sprinkles({ sprinkles({
backgroundColor: 'backgroundSurface', backgroundColor: 'backgroundSurface',
borderColor: 'transparent', borderColor: 'backgroundOutline',
}), }),
{
':hover': {
backgroundColor: themeVars.colors.stateOverlayHover,
},
},
]) ])
export const cardImageHover = style({ export const cardImageHover = style({
...@@ -45,9 +49,15 @@ export const cardImageHover = style({ ...@@ -45,9 +49,15 @@ export const cardImageHover = style({
export const selectedCard = style([ export const selectedCard = style([
card, card,
sprinkles({ sprinkles({
background: 'lightGrayOverlay', background: 'backgroundSurface',
borderColor: 'backgroundOutline', borderColor: 'accentAction',
borderWidth: '3px',
}), }),
{
':hover': {
backgroundColor: themeVars.colors.stateOverlayHover,
},
},
]) ])
export const button = style([ export const button = style([
......
import clsx from 'clsx' import clsx from 'clsx'
import Column from 'components/Column'
import { MouseoverTooltip } from 'components/Tooltip' import { MouseoverTooltip } from 'components/Tooltip'
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 { import {
ChevronRightIcon,
MinusIconLarge, MinusIconLarge,
PauseButtonIcon, PauseButtonIcon,
PlayButtonIcon, PlayButtonIcon,
PlusIconLarge, PlusIconLarge,
PoolIcon, PoolIcon,
RarityVerifiedIcon, RarityVerifiedIcon,
SuspiciousIcon20,
} from 'nft/components/icons' } from 'nft/components/icons'
import { body, bodySmall, subheadSmall } from 'nft/css/common.css' import { body, bodySmall } 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, UniformHeight, UniformHeights } from 'nft/types' import { GenieAsset, Rarity, UniformHeight, UniformHeights } from 'nft/types'
...@@ -28,6 +27,9 @@ import { ...@@ -28,6 +27,9 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import { AlertTriangle } from 'react-feather'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
import * as styles from './Card.css' import * as styles from './Card.css'
...@@ -38,6 +40,8 @@ export interface CardContextProps { ...@@ -38,6 +40,8 @@ export interface CardContextProps {
selected: boolean selected: boolean
href: string href: string
setHref: (href: string) => void setHref: (href: string) => void
addAssetToBag: () => void
removeAssetFromBag: () => void
} }
const CardContext = createContext<CardContextProps | undefined>(undefined) const CardContext = createContext<CardContextProps | undefined>(undefined)
...@@ -50,14 +54,85 @@ const useCardContext = () => { ...@@ -50,14 +54,85 @@ const useCardContext = () => {
const baseHref = (asset: GenieAsset) => `/#/nfts/asset/${asset.address}/${asset.tokenId}?origin=collection` const baseHref = (asset: GenieAsset) => `/#/nfts/asset/${asset.address}/${asset.tokenId}?origin=collection`
const DetailsLinkContainer = styled.a`
display: flex;
flex-shrink: 0;
text-decoration: none;
color: ${({ theme }) => theme.textSecondary};
font-size: 14px;
line-height: 20px;
weight: 400;
:hover {
color: ${({ theme }) => theme.accentAction};
}
`
const SuspiciousIcon = styled(AlertTriangle)`
width: 16px;
height: 16px;
color: ${({ theme }) => theme.accentFailure};
`
const Erc1155ControlsRow = styled.div`
position: absolute;
display: flex;
width: 100%;
bottom: 12px;
z-index: 2;
justify-content: center;
`
const Erc1155ControlsContainer = styled.div`
display: flex;
border: 1px solid ${({ theme }) => theme.backgroundOutline};
border-radius: 12px 12px 12px 12px;
overflow: hidden;
`
const Erc1155ControlsDisplay = styled(ThemedText.HeadlineSmall)`
display: flex;
padding: 6px 8px;
width: 60px;
background: ${({ theme }) => theme.backgroundBackdrop};
justify-content: center;
cursor: default;
`
const Erc1155ControlsInput = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 40px;
background: ${({ theme }) => theme.backgroundInteractive};
color: ${({ theme }) => theme.textPrimary};
:hover {
color: ${({ theme }) => theme.accentAction};
}
`
const RankingContainer = styled.div`
position: absolute;
top: 12px;
left: 12px;
z-index: 2;
`
const StyledImageContainer = styled.div`
position: relative;
`
/* -------- ASSET CARD -------- */ /* -------- ASSET CARD -------- */
interface CardProps { interface CardProps {
asset: GenieAsset asset: GenieAsset
selected: boolean selected: boolean
addAssetToBag: () => void
removeAssetFromBag: () => void
children: ReactNode children: ReactNode
} }
const Container = ({ asset, selected, children }: CardProps) => { const Container = ({ asset, selected, addAssetToBag, removeAssetFromBag, children }: CardProps) => {
const [hovered, toggleHovered] = useReducer((s) => !s, false) const [hovered, toggleHovered] = useReducer((s) => !s, false)
const [href, setHref] = useState(baseHref(asset)) const [href, setHref] = useState(baseHref(asset))
...@@ -69,8 +144,10 @@ const Container = ({ asset, selected, children }: CardProps) => { ...@@ -69,8 +144,10 @@ const Container = ({ asset, selected, children }: CardProps) => {
toggleHovered, toggleHovered,
href, href,
setHref, setHref,
addAssetToBag,
removeAssetFromBag,
}), }),
[asset, hovered, selected, href] [asset, hovered, selected, href, addAssetToBag, removeAssetFromBag]
) )
const assetRef = useRef<HTMLDivElement>(null) const assetRef = useRef<HTMLDivElement>(null)
...@@ -82,16 +159,21 @@ const Container = ({ asset, selected, children }: CardProps) => { ...@@ -82,16 +159,21 @@ const Container = ({ asset, selected, children }: CardProps) => {
return ( return (
<CardContext.Provider value={providerValue}> <CardContext.Provider value={providerValue}>
<Box <Box
as="a"
href={href ? href : baseHref(asset)}
position={'relative'} position={'relative'}
ref={assetRef} ref={assetRef}
borderRadius={'20'} borderRadius={'20'}
className={styles.notSelectedCard} className={selected ? styles.selectedCard : styles.notSelectedCard}
draggable={false} draggable={false}
onMouseEnter={() => toggleHovered()} onMouseEnter={() => toggleHovered()}
onMouseLeave={() => toggleHovered()} onMouseLeave={() => toggleHovered()}
transition="250" transition="250"
cursor={asset.notForSale ? 'default' : 'pointer'}
onClick={(e: MouseEvent) => {
if (!asset.notForSale) {
e.preventDefault()
!selected ? addAssetToBag() : removeAssetFromBag()
}
}}
> >
{children} {children}
</Box> </Box>
...@@ -99,6 +181,10 @@ const Container = ({ asset, selected, children }: CardProps) => { ...@@ -99,6 +181,10 @@ const Container = ({ asset, selected, children }: CardProps) => {
) )
} }
const ImageContainer = ({ children }: { children: ReactNode }) => (
<StyledImageContainer>{children}</StyledImageContainer>
)
/* -------- CARD IMAGE -------- */ /* -------- CARD IMAGE -------- */
interface ImageProps { interface ImageProps {
uniformHeight: UniformHeight uniformHeight: UniformHeight
...@@ -365,10 +451,14 @@ const InfoContainer = ({ children }: { children: ReactNode }) => { ...@@ -365,10 +451,14 @@ const InfoContainer = ({ children }: { children: ReactNode }) => {
) )
} }
const PrimaryRow = ({ children }: { children: ReactNode }) => <Row justifyContent="space-between">{children}</Row> const PrimaryRow = ({ children }: { children: ReactNode }) => (
<Row gap="8" justifyContent="space-between">
{children}
</Row>
)
const PrimaryDetails = ({ children }: { children: ReactNode }) => ( const PrimaryDetails = ({ children }: { children: ReactNode }) => (
<Row overflow="hidden" whiteSpace="nowrap"> <Row justifyItems="center" overflow="hidden" whiteSpace="nowrap">
{children} {children}
</Row> </Row>
) )
...@@ -425,100 +515,35 @@ const TertiaryInfo = ({ children }: { children: ReactNode }) => { ...@@ -425,100 +515,35 @@ const TertiaryInfo = ({ children }: { children: ReactNode }) => {
) )
} }
interface ButtonProps { interface Erc1155ControlsInterface {
children: ReactNode quantity: string
quantity: number
selectedChildren: ReactNode
onClick: (e: MouseEvent) => void
onSelectedClick: (e: MouseEvent) => void
} }
const Button = ({ children, quantity, selectedChildren, onClick, onSelectedClick }: ButtonProps) => { const Erc1155Controls = ({ quantity }: Erc1155ControlsInterface) => {
const [buttonHovered, toggleButtonHovered] = useReducer((s) => !s, false) const { addAssetToBag, removeAssetFromBag } = useCardContext()
const { asset, selected, setHref } = useCardContext()
const buttonRef = useRef<HTMLDivElement>(null)
const isMobile = useIsMobile()
useLayoutEffect(() => {
if (buttonHovered && buttonRef.current?.matches(':hover') === false) toggleButtonHovered()
}, [buttonHovered])
return ( return (
<> <Erc1155ControlsRow>
{!selected || asset.tokenType !== 'ERC1155' ? ( <Erc1155ControlsContainer>
<Box <Erc1155ControlsInput
as="button" onClick={(e: MouseEvent) => {
ref={buttonRef} e.stopPropagation()
color={ removeAssetFromBag()
buttonHovered || isMobile
? 'explicitWhite'
: selected
? 'accentFailure'
: asset.notForSale
? 'textTertiary'
: 'accentAction'
}
background={
buttonHovered || isMobile
? asset.notForSale
? 'backgroundInteractive'
: selected
? 'accentFailure'
: 'accentAction'
: asset.notForSale
? 'backgroundModule'
: selected
? 'accentFailureSoft'
: 'accentActionSoft'
}
className={clsx(styles.button, subheadSmall)}
onClick={(e) =>
selected
? onSelectedClick(e)
: asset.notForSale
? () => {
return true
}
: onClick(e)
}
onMouseEnter={() => {
!asset.notForSale && setHref('')
!buttonHovered && toggleButtonHovered()
}}
onMouseLeave={() => {
!asset.notForSale && setHref(baseHref(asset))
buttonHovered && toggleButtonHovered()
}} }}
transition="250"
> >
{selected <MinusIconLarge width="24px" height="24px" />
? selectedChildren </Erc1155ControlsInput>
: asset.notForSale <Erc1155ControlsDisplay>{quantity}</Erc1155ControlsDisplay>
? buttonHovered || isMobile <Erc1155ControlsInput
? 'See details' onClick={(e: MouseEvent) => {
: 'Not for sale' e.stopPropagation()
: children} addAssetToBag()
</Box> }}
) : (
<Row className={styles.erc1155ButtonRow}>
<Column
as="button"
className={styles.erc1155MinusButton}
onClick={(e: MouseEvent<Element, globalThis.MouseEvent>) => onSelectedClick(e)}
>
<MinusIconLarge width="32" height="32" />
</Column>
<Box className={`${styles.erc1155QuantityText} ${subheadSmall}`}>{quantity.toString()}</Box>
<Column
as="button"
className={styles.erc1155PlusButton}
onClick={(e: MouseEvent<Element, globalThis.MouseEvent>) => onClick(e)}
> >
<PlusIconLarge width="32" height="32" /> <PlusIconLarge width="24px" height="24px" />
</Column> </Erc1155ControlsInput>
</Row> </Erc1155ControlsContainer>
)} </Erc1155ControlsRow>
</>
) )
} }
...@@ -533,6 +558,22 @@ const MarketplaceIcon = ({ marketplace }: { marketplace: string }) => { ...@@ -533,6 +558,22 @@ const MarketplaceIcon = ({ marketplace }: { marketplace: string }) => {
) )
} }
const DetailsLink = () => {
const { asset } = useCardContext()
return (
<DetailsLinkContainer
href={baseHref(asset)}
onClick={(e: MouseEvent) => {
e.stopPropagation()
}}
>
Details
<ChevronRightIcon width="20px" height="20px" />
</DetailsLinkContainer>
)
}
/* -------- RANKING CARD -------- */ /* -------- RANKING CARD -------- */
interface RankingProps { interface RankingProps {
rarity: Rarity rarity: Rarity
...@@ -545,6 +586,7 @@ const Ranking = ({ rarity, provider, rarityVerified, rarityLogo }: RankingProps) ...@@ -545,6 +586,7 @@ const Ranking = ({ rarity, provider, rarityVerified, rarityLogo }: RankingProps)
const { asset } = useCardContext() const { asset } = useCardContext()
return ( return (
<RankingContainer>
<MouseoverTooltip <MouseoverTooltip
text={ text={
<Row> <Row>
...@@ -570,6 +612,7 @@ const Ranking = ({ rarity, provider, rarityVerified, rarityLogo }: RankingProps) ...@@ -570,6 +612,7 @@ const Ranking = ({ rarity, provider, rarityVerified, rarityLogo }: RankingProps)
</Box> </Box>
</Box> </Box>
</MouseoverTooltip> </MouseoverTooltip>
</RankingContainer>
) )
} }
const SUSPICIOUS_TEXT = 'Blocked on OpenSea' const SUSPICIOUS_TEXT = 'Blocked on OpenSea'
...@@ -577,8 +620,8 @@ const SUSPICIOUS_TEXT = 'Blocked on OpenSea' ...@@ -577,8 +620,8 @@ const SUSPICIOUS_TEXT = 'Blocked on OpenSea'
const Suspicious = () => { const Suspicious = () => {
return ( return (
<MouseoverTooltip text={<Box className={bodySmall}>{SUSPICIOUS_TEXT}</Box>} placement="top"> <MouseoverTooltip text={<Box className={bodySmall}>{SUSPICIOUS_TEXT}</Box>} placement="top">
<Box display="flex" flexShrink="0" marginLeft="2"> <Box display="flex" flexShrink="0" marginLeft="4">
<SuspiciousIcon20 width="20" height="20" /> <SuspiciousIcon />
</Box> </Box>
</MouseoverTooltip> </MouseoverTooltip>
) )
...@@ -632,7 +675,7 @@ const NoContentContainer = ({ uniformHeight }: NoContentContainerProps) => ( ...@@ -632,7 +675,7 @@ const NoContentContainer = ({ uniformHeight }: NoContentContainerProps) => (
width="full" width="full"
style={{ style={{
paddingTop: '100%', paddingTop: '100%',
background: `linear-gradient(270deg, ${themeVars.colors.backgroundOutline} 0%, ${themeVars.colors.backgroundSurface} 100%)`, background: `linear-gradient(90deg, ${themeVars.colors.backgroundSurface} 0%, ${themeVars.colors.backgroundInteractive} 95.83%)`,
}} }}
> >
<Box <Box
...@@ -656,10 +699,12 @@ const NoContentContainer = ({ uniformHeight }: NoContentContainerProps) => ( ...@@ -656,10 +699,12 @@ const NoContentContainer = ({ uniformHeight }: NoContentContainerProps) => (
export { export {
Audio, Audio,
Button,
Container, Container,
DetailsContainer, DetailsContainer,
DetailsLink,
Erc1155Controls,
Image, Image,
ImageContainer,
InfoContainer, InfoContainer,
MarketplaceIcon, MarketplaceIcon,
Pool, Pool,
......
...@@ -2,7 +2,7 @@ import { BigNumber } from '@ethersproject/bignumber' ...@@ -2,7 +2,7 @@ import { BigNumber } from '@ethersproject/bignumber'
import { useBag } from 'nft/hooks' import { useBag } from 'nft/hooks'
import { GenieAsset, Markets, UniformHeight } from 'nft/types' import { GenieAsset, Markets, UniformHeight } from 'nft/types'
import { formatWeiToDecimal, isAudio, isVideo, rarityProviderLogo } from 'nft/utils' import { formatWeiToDecimal, isAudio, isVideo, rarityProviderLogo } from 'nft/utils'
import { MouseEvent, useMemo } from 'react' import { useMemo } from 'react'
import * as Card from './Card' import * as Card from './Card'
...@@ -73,7 +73,27 @@ export const CollectionAsset = ({ ...@@ -73,7 +73,27 @@ export const CollectionAsset = ({
}, [asset]) }, [asset])
return ( return (
<Card.Container asset={asset} selected={isSelected}> <Card.Container
asset={asset}
selected={isSelected}
addAssetToBag={() => {
addAssetsToBag([asset])
!bagExpanded && !isMobile && toggleBag()
}}
removeAssetFromBag={() => {
removeAssetsFromBag([asset])
}}
>
<Card.ImageContainer>
{asset.tokenType === 'ERC1155' && quantity > 0 && <Card.Erc1155Controls quantity={quantity.toString()} />}
{asset.rarity && provider && provider.rank && (
<Card.Ranking
rarity={asset.rarity}
provider={provider}
rarityVerified={!!rarityVerified}
rarityLogo={rarityLogo}
/>
)}
{assetMediaType === AssetMediaType.Image ? ( {assetMediaType === AssetMediaType.Image ? (
<Card.Image uniformHeight={uniformHeight} setUniformHeight={setUniformHeight} /> <Card.Image uniformHeight={uniformHeight} setUniformHeight={setUniformHeight} />
) : assetMediaType === AssetMediaType.Video ? ( ) : assetMediaType === AssetMediaType.Video ? (
...@@ -91,6 +111,7 @@ export const CollectionAsset = ({ ...@@ -91,6 +111,7 @@ export const CollectionAsset = ({
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
/> />
)} )}
</Card.ImageContainer>
<Card.DetailsContainer> <Card.DetailsContainer>
<Card.InfoContainer> <Card.InfoContainer>
<Card.PrimaryRow> <Card.PrimaryRow>
...@@ -98,14 +119,7 @@ export const CollectionAsset = ({ ...@@ -98,14 +119,7 @@ export const CollectionAsset = ({
<Card.PrimaryInfo>{asset.name ? asset.name : `#${asset.tokenId}`}</Card.PrimaryInfo> <Card.PrimaryInfo>{asset.name ? asset.name : `#${asset.tokenId}`}</Card.PrimaryInfo>
{asset.susFlag && <Card.Suspicious />} {asset.susFlag && <Card.Suspicious />}
</Card.PrimaryDetails> </Card.PrimaryDetails>
{asset.rarity && provider && provider.rank && ( <Card.DetailsLink />
<Card.Ranking
rarity={asset.rarity}
provider={provider}
rarityVerified={!!rarityVerified}
rarityLogo={rarityLogo}
/>
)}
</Card.PrimaryRow> </Card.PrimaryRow>
<Card.SecondaryRow> <Card.SecondaryRow>
<Card.SecondaryDetails> <Card.SecondaryDetails>
...@@ -119,21 +133,6 @@ export const CollectionAsset = ({ ...@@ -119,21 +133,6 @@ export const CollectionAsset = ({
)} )}
</Card.SecondaryRow> </Card.SecondaryRow>
</Card.InfoContainer> </Card.InfoContainer>
<Card.Button
quantity={quantity}
selectedChildren={'Remove'}
onClick={(e: MouseEvent) => {
e.preventDefault()
addAssetsToBag([asset])
!bagExpanded && !isMobile && toggleBag()
}}
onSelectedClick={(e: MouseEvent) => {
e.preventDefault()
removeAssetsFromBag([asset])
}}
>
{'Buy now'}
</Card.Button>
</Card.DetailsContainer> </Card.DetailsContainer>
</Card.Container> </Card.Container>
) )
......
...@@ -14,14 +14,9 @@ export const CollectionAssetLoading = () => { ...@@ -14,14 +14,9 @@ export const CollectionAssetLoading = () => {
</Box> </Box>
<Row justifyContent="space-between" marginTop="12" paddingLeft="12" paddingRight="12"> <Row justifyContent="space-between" marginTop="12" paddingLeft="12" paddingRight="12">
<Box as="div" className={loadingAsset} height="12" width="120"></Box> <Box as="div" className={loadingAsset} height="12" width="120"></Box>
<Box as="div" className={loadingAsset} width="36" height="12"></Box>
</Row> </Row>
<Row justifyContent="space-between" marginTop="12" paddingLeft="12" paddingRight="12"> <Row justifyContent="space-between" marginTop="12" paddingLeft="12" paddingRight="12">
<Box as="div" className={loadingAsset} height="16" width="80"></Box> <Box as="div" className={loadingAsset} height="16" width="80"></Box>
<Box as="div" className={loadingAsset} width="16" height="16" borderRadius="4"></Box>
</Row>
<Row marginTop="12" paddingLeft="12" paddingRight="12">
<Box as="div" className={loadingAsset} width="full" height="32"></Box>
</Row> </Row>
</Box> </Box>
) )
......
...@@ -1239,20 +1239,15 @@ export const SuspiciousIcon20 = (props: SVGProps) => ( ...@@ -1239,20 +1239,15 @@ export const SuspiciousIcon20 = (props: SVGProps) => (
) )
export const MinusIconLarge = (props: SVGProps) => ( export const MinusIconLarge = (props: SVGProps) => (
<svg fill="none" xmlns="http://www.w3.org/2000/svg" {...props}> <svg {...props} fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path d="M5 12H19" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
d="M8.72879 16.7601H23.2734C23.8862 16.7601 24.4085 16.2478 24.4085 15.615C24.4085 14.9922 23.8862 14.4699 23.2734 14.4699H8.72879C8.13616 14.4699 7.59375 14.9922 7.59375 15.615C7.59375 16.2478 8.13616 16.7601 8.72879 16.7601Z"
fill="currentColor"
/>
</svg> </svg>
) )
export const PlusIconLarge = (props: SVGProps) => ( export const PlusIconLarge = (props: SVGProps) => (
<svg fill="none" xmlns="http://www.w3.org/2000/svg" {...props}> <svg {...props} fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path d="M12 5V19" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
d="M8.72712 16.75H14.8544V22.8772C14.8544 23.5 15.3666 24.0223 15.9994 24.0223C16.6323 24.0223 17.1445 23.5 17.1445 22.8772V16.75H23.2718C23.8945 16.75 24.4169 16.2377 24.4169 15.6049C24.4169 14.9721 23.8945 14.4598 23.2718 14.4598H17.1445V8.33259C17.1445 7.70982 16.6323 7.1875 15.9994 7.1875C15.3666 7.1875 14.8544 7.70982 14.8544 8.33259V14.4598H8.72712C8.10435 14.4598 7.58203 14.9721 7.58203 15.6049C7.58203 16.2377 8.10435 16.75 8.72712 16.75Z" <path d="M5 12H19" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
fill="currentColor"
/>
</svg> </svg>
) )
......
...@@ -265,7 +265,7 @@ const flexAlignment = [ ...@@ -265,7 +265,7 @@ const flexAlignment = [
const overflow = ['hidden', 'inherit', 'scroll', 'visible', 'auto'] as const const overflow = ['hidden', 'inherit', 'scroll', 'visible', 'auto'] as const
const borderWidth = ['0px', '0.5px', '1px', '1.5px', '2px', '4px'] const borderWidth = ['0px', '0.5px', '1px', '1.5px', '2px', '3px', '4px']
const borderStyle = ['none', 'solid'] as const const borderStyle = ['none', 'solid'] as const
......
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