Commit 7bf74102 authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

feat: profile listing sidebar (#4809)

* Add sell header to Bag

* split bag content to its own file

* empty tag state

* continue button

* file re-arranging and add profile select row content

* update padding

* better null check
Co-authored-by: default avatarCharles Bachmeier <charlie@genie.xyz>
parent 0017e2fc
...@@ -10,7 +10,6 @@ import { useLocation } from 'react-router-dom' ...@@ -10,7 +10,6 @@ import { useLocation } from 'react-router-dom'
import { useModalIsOpen, useToggleModal } from 'state/application/hooks' import { useModalIsOpen, useToggleModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer' import { ApplicationModal } from 'state/application/reducer'
const Cart = lazy(() => import('nft/components/profile/modal/ListingTag'))
const Bag = lazy(() => import('nft/components/bag/Bag')) const Bag = lazy(() => import('nft/components/bag/Bag'))
const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal')) const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal'))
...@@ -30,7 +29,6 @@ export default function TopLevelModals() { ...@@ -30,7 +29,6 @@ export default function TopLevelModals() {
<ConnectedAccountBlocked account={account} isOpen={open} /> <ConnectedAccountBlocked account={account} isOpen={open} />
{useTokensFlag() === TokensVariant.Enabled && {useTokensFlag() === TokensVariant.Enabled &&
(location.pathname.includes('/pool') || location.pathname.includes('/swap')) && <TokensBanner />} (location.pathname.includes('/pool') || location.pathname.includes('/swap')) && <TokensBanner />}
<Cart />
<Bag /> <Bag />
{useNftFlag() === NftVariant.Enabled && <TransactionCompleteModal />} {useNftFlag() === NftVariant.Enabled && <TransactionCompleteModal />}
</> </>
......
import { style } from '@vanilla-extract/css' import { style } from '@vanilla-extract/css'
import { subhead } from 'nft/css/common.css' import { breakpoints, sprinkles } from 'nft/css/sprinkles.css'
import { breakpoints, sprinkles, vars } from 'nft/css/sprinkles.css'
export const bagContainer = style([ export const bagContainer = style([
sprinkles({ sprinkles({
...@@ -35,27 +34,3 @@ export const assetsContainer = style([ ...@@ -35,27 +34,3 @@ export const assetsContainer = style([
scrollbarWidth: 'none', scrollbarWidth: 'none',
}, },
]) ])
export const header = style([
subhead,
sprinkles({
color: 'textPrimary',
justifyContent: 'space-between',
}),
{
lineHeight: '24px',
},
])
export const clearAll = style([
sprinkles({
color: 'textTertiary',
cursor: 'pointer',
fontWeight: 'semibold',
}),
{
':hover': {
color: vars.color.blue400,
},
},
])
This diff is collapsed.
import { BagRow, PriceChangeBagRow, UnavailableAssetsHeaderRow } from 'nft/components/bag/BagRow'
import { Column } from 'nft/components/Flex'
import { useBag, useIsMobile } from 'nft/hooks'
import { BagItemStatus, BagStatus } from 'nft/types'
import { recalculateBagUsingPooledAssets } from 'nft/utils/calcPoolPrice'
import { fetchPrice } from 'nft/utils/fetchPrice'
import { useEffect, useMemo } from 'react'
import { useQuery } from 'react-query'
export const BagContent = () => {
const bagStatus = useBag((s) => s.bagStatus)
const setBagStatus = useBag((s) => s.setBagStatus)
const markAssetAsReviewed = useBag((s) => s.markAssetAsReviewed)
const didOpenUnavailableAssets = useBag((s) => s.didOpenUnavailableAssets)
const setDidOpenUnavailableAssets = useBag((s) => s.setDidOpenUnavailableAssets)
const uncheckedItemsInBag = useBag((s) => s.itemsInBag)
const setItemsInBag = useBag((s) => s.setItemsInBag)
const removeAssetFromBag = useBag((s) => s.removeAssetFromBag)
const isMobile = useIsMobile()
const itemsInBag = useMemo(() => {
return recalculateBagUsingPooledAssets(uncheckedItemsInBag)
}, [uncheckedItemsInBag])
const { data: fetchedPriceData } = useQuery(['fetchPrice', {}], () => fetchPrice(), {})
const { unchangedAssets, priceChangedAssets, unavailableAssets, availableItems } = useMemo(() => {
const unchangedAssets = itemsInBag
.filter((item) => item.status === BagItemStatus.ADDED_TO_BAG || item.status === BagItemStatus.REVIEWED)
.map((item) => item.asset)
const priceChangedAssets = itemsInBag
.filter((item) => item.status === BagItemStatus.REVIEWING_PRICE_CHANGE)
.map((item) => item.asset)
const unavailableAssets = itemsInBag
.filter((item) => item.status === BagItemStatus.UNAVAILABLE)
.map((item) => item.asset)
const availableItems = itemsInBag.filter((item) => item.status !== BagItemStatus.UNAVAILABLE)
return { unchangedAssets, priceChangedAssets, unavailableAssets, availableItems }
}, [itemsInBag])
useEffect(() => {
const hasAssetsInReview = priceChangedAssets.length > 0
const hasAssets = itemsInBag.length > 0
if (bagStatus === BagStatus.IN_REVIEW && !hasAssetsInReview) {
if (hasAssets) setBagStatus(BagStatus.CONFIRM_REVIEW)
else setBagStatus(BagStatus.ADDING_TO_BAG)
}
}, [bagStatus, itemsInBag, priceChangedAssets, setBagStatus])
return (
<>
<Column display={priceChangedAssets.length > 0 || unavailableAssets.length > 0 ? 'flex' : 'none'}>
{unavailableAssets.length > 0 && (
<UnavailableAssetsHeaderRow
assets={unavailableAssets}
usdPrice={fetchedPriceData}
clearUnavailableAssets={() => setItemsInBag(availableItems)}
didOpenUnavailableAssets={didOpenUnavailableAssets}
setDidOpenUnavailableAssets={setDidOpenUnavailableAssets}
isMobile={isMobile}
/>
)}
{priceChangedAssets.map((asset, index) => (
<PriceChangeBagRow
key={asset.id}
asset={asset}
usdPrice={fetchedPriceData}
markAssetAsReviewed={markAssetAsReviewed}
top={index === 0 && unavailableAssets.length === 0}
isMobile={isMobile}
/>
))}
</Column>
<Column gap="8">
{unchangedAssets.map((asset) => (
<BagRow
key={asset.id}
asset={asset}
usdPrice={fetchedPriceData}
removeAsset={removeAssetFromBag}
showRemove={true}
isMobile={isMobile}
/>
))}
</Column>
</>
)
}
import { style } from '@vanilla-extract/css'
import { subhead } from 'nft/css/common.css'
import { sprinkles, vars } from 'nft/css/sprinkles.css'
export const header = style([
subhead,
sprinkles({
color: 'textPrimary',
justifyContent: 'space-between',
}),
{
lineHeight: '24px',
},
])
export const clearAll = style([
sprinkles({
color: 'textTertiary',
cursor: 'pointer',
fontWeight: 'semibold',
}),
{
':hover': {
color: vars.color.blue400,
},
},
])
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'
import * as styles from './BagHeader.css'
interface BagHeaderProps {
numberOfAssets: number
toggleBag: () => void
resetFlow: () => void
isProfilePage: boolean
}
export const BagHeader = ({ numberOfAssets, toggleBag, resetFlow, isProfilePage }: BagHeaderProps) => {
return (
<Column gap="4" paddingX="32" marginBottom="20">
<Row className={styles.header}>
{isProfilePage ? 'Sell NFTs' : 'My bag'}
<Box display="flex" padding="2" color="textSecondary" cursor="pointer" onClick={toggleBag}>
<BagCloseIcon />
</Box>
</Row>
{numberOfAssets > 0 && (
<Box fontSize="14" fontWeight="normal" style={{ lineHeight: '20px' }} color="textPrimary">
{roundAndPluralize(numberOfAssets, 'NFT')} ·{' '}
<Box
as="span"
className={styles.clearAll}
onClick={() => {
resetFlow()
}}
>
Clear all
</Box>
</Box>
)}
</Column>
)
}
import { style } from '@vanilla-extract/css' import { style } from '@vanilla-extract/css'
import { buttonTextSmall } from 'nft/css/common.css'
import { sprinkles } from 'nft/css/sprinkles.css' import { sprinkles } from 'nft/css/sprinkles.css'
export const tagAssetImage = style([ export const tagAssetImage = style([
sprinkles({ sprinkles({
borderRadius: '8', borderRadius: '8',
height: '52', height: '56',
width: '52', width: '56',
marginRight: '12', marginX: '12',
marginLeft: '8',
cursor: 'pointer',
}),
{
boxSizing: 'border-box',
},
])
export const tagAssetName = style([
sprinkles({
fontWeight: 'medium',
overflow: 'hidden',
marginRight: 'auto',
marginTop: '4',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}),
])
export const tagAssetCollectionName = style([
sprinkles({
fontWeight: 'normal',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}), }),
{
maxWidth: '65%',
},
])
export const tagAssetRowBottom = style([
sprinkles({
width: 'full',
display: 'flex',
flexWrap: 'nowrap',
marginRight: '4',
}),
{
marginTop: '-10px',
},
]) ])
export const removeAsset = style([ export const removeAsset = style([
...@@ -56,8 +17,8 @@ export const removeAsset = style([ ...@@ -56,8 +17,8 @@ export const removeAsset = style([
cursor: 'pointer', cursor: 'pointer',
}), }),
{ {
bottom: '-12px', bottom: '-4px',
left: '22px', left: '24px',
}, },
]) ])
...@@ -67,16 +28,14 @@ export const removeIcon = style([ ...@@ -67,16 +28,14 @@ export const removeIcon = style([
}), }),
]) ])
export const tagAssetInfo = style([ export const removeBagRowButton = style([
buttonTextSmall,
sprinkles({ sprinkles({
fontSize: '14', background: 'backgroundInteractive',
color: 'textPrimary', color: 'textPrimary',
display: 'flex', paddingX: '14',
flexWrap: 'wrap', paddingY: '12',
width: 'full', borderRadius: '12',
overflowX: 'hidden', cursor: 'pointer',
}), }),
{
lineHeight: '17px',
},
]) ])
import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex'
import { bodySmall, subhead } from 'nft/css/common.css'
import { useIsMobile, useSellAsset } from 'nft/hooks'
import { WalletAsset } from 'nft/types'
import { useState } from 'react'
import * as styles from './ProfileAssetRow.css'
const ProfileAssetRow = ({ asset }: { asset: WalletAsset }) => {
const removeAsset = useSellAsset((state) => state.removeSellAsset)
const isMobile = useIsMobile()
const [hovered, setHovered] = useState(false)
const handleHover = () => setHovered(!hovered)
return (
<Row paddingY="8" position="relative" onMouseEnter={handleHover} onMouseLeave={handleHover}>
<div>
<Box
display={isMobile ? 'flex' : 'none'}
className={styles.removeAsset}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
removeAsset(asset)
}}
>
<img className={styles.removeIcon} src={'/nft/svgs/minusCircle.svg'} alt="Remove item" />
</Box>
<img className={styles.tagAssetImage} src={asset.image_url} alt={asset.name} />
</div>
<Column gap="4" overflow="hidden" flexWrap="nowrap">
<Box overflow="hidden" textOverflow="ellipsis" whiteSpace="nowrap" className={subhead}>
{asset.name ?? `#${asset.tokenId}`}
</Box>
<Box overflow="hidden" textOverflow="ellipsis" whiteSpace="nowrap" className={bodySmall}>
{asset.collection?.name}
</Box>
</Column>
{hovered && !isMobile && (
<Box
marginLeft="auto"
marginRight="0"
className={styles.removeBagRowButton}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
removeAsset(asset)
}}
>
Remove
</Box>
)}
</Row>
)
}
export default ProfileAssetRow
import { Column } from 'nft/components/Flex'
import { useSellAsset } from 'nft/hooks'
import ProfileAssetRow from './ProfileAssetRow'
export const ProfileBagContent = () => {
const sellAssets = useSellAsset((state) => state.sellAssets)
return (
<Column>
{sellAssets.length ? sellAssets.map((asset, index) => <ProfileAssetRow asset={asset} key={index} />) : null}
</Column>
)
}
...@@ -1396,6 +1396,19 @@ export const LargeBagIcon = (props: SVGProps) => ( ...@@ -1396,6 +1396,19 @@ export const LargeBagIcon = (props: SVGProps) => (
</svg> </svg>
) )
export const LargeTagIcon = (props: SVGProps) => (
<svg width="96" height="96" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M55.6215 80.6815L55.621 80.6819C55.0823 81.2212 54.4427 81.649 53.7386 81.9409C53.0345 82.2328 52.2797 82.383 51.5175 82.383C50.7553 82.383 50.0006 82.2328 49.2965 81.9409C48.5923 81.649 47.9527 81.2212 47.414 80.6819L47.413 80.681L17.7 51.0025V17.7H51.0029L80.714 47.411C80.7141 47.4111 80.7142 47.4112 80.7143 47.4113C81.7943 48.498 82.4006 49.9679 82.4006 51.5C82.4006 53.032 81.7944 54.5017 80.7146 55.5884C80.7144 55.5886 80.7142 55.5888 80.714 55.589L55.6215 80.6815Z"
stroke="currentColor"
strokeWidth="2.4"
strokeLinecap="round"
strokeLinejoin="round"
/>
<circle cx="34" cy="34" r="3" fill="currentColor" />
</svg>
)
export const CircularCloseIcon = (props: SVGProps) => ( export const CircularCloseIcon = (props: SVGProps) => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<circle cx="8" cy="8" r="8" fill="#293249" /> <circle cx="8" cy="8" r="8" fill="#293249" />
......
import clsx from 'clsx' import clsx from 'clsx'
import ms from 'ms.macro' import ms from 'ms.macro'
import { ListingButton } from 'nft/components/bag/profile/ListingButton'
import { getListingState } from 'nft/components/bag/profile/utils'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { SortDropdown } from 'nft/components/common/SortDropdown' import { SortDropdown } from 'nft/components/common/SortDropdown'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
...@@ -41,8 +43,6 @@ import { ListingMarkets } from 'nft/utils/listNfts' ...@@ -41,8 +43,6 @@ import { ListingMarkets } from 'nft/utils/listNfts'
import { pluralize } from 'nft/utils/roundAndPluralize' import { pluralize } from 'nft/utils/roundAndPluralize'
import { Dispatch, FormEvent, useEffect, useMemo, useRef, useState } from 'react' import { Dispatch, FormEvent, useEffect, useMemo, useRef, useState } from 'react'
import { ListingButton } from '../modal/ListingButton'
import { getListingState } from '../modal/utils'
import * as styles from './ListPage.css' import * as styles from './ListPage.css'
const SelectMarketplacesModal = ({ const SelectMarketplacesModal = ({
......
import { style } from '@vanilla-extract/css'
import { breakpoints, sprinkles } from 'nft/css/sprinkles.css'
export const tagContainer = style([
sprinkles({
borderRadius: '20',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: 'backgroundOutline',
}),
{
'@media': {
[`screen and (max-width: ${breakpoints.md}px)`]: {
borderRadius: '0',
},
},
},
])
export const tagAssets = style([
sprinkles({
maxHeight: 'inherit',
}),
{
'@media': {
[`screen and (min-width: ${breakpoints.md}px)`]: {
maxHeight: '55vh',
},
},
'::-webkit-scrollbar': { display: 'none' },
scrollbarWidth: 'none',
},
])
export const closeIcon = style({
transform: 'rotate(90deg)',
float: 'right',
paddingTop: '1px',
})
export const orderButton = style([
sprinkles({
width: 'full',
paddingY: '12',
paddingX: '0',
}),
{
':hover': {
boxShadow: 'none',
},
},
])
import Loader from 'components/Loader'
import { Box } from 'nft/components/Box'
import { Column } from 'nft/components/Flex'
import { CloseDropDownIcon } from 'nft/components/icons'
import { bodySmall, buttonMedium, headlineSmall } from 'nft/css/common.css'
import { useBag, useIsMobile, useProfilePageState, useSellAsset } from 'nft/hooks'
import { ProfilePageStateType } from 'nft/types'
import { lazy, Suspense } from 'react'
import { useLocation } from 'react-router-dom'
import * as styles from './ListingTag.css'
const CartSellAssetRow = lazy(() => import('./TagAssetRow'))
const ListingModal = lazy(() => import('./ListingModal'))
const Cart = () => {
const { pathname } = useLocation()
const isProfilePage = pathname.startsWith('/profile')
const sellAssets = useSellAsset((state) => state.sellAssets)
const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
const sellPageState = useProfilePageState((state) => state.state)
const toggleCart = useBag((state) => state.toggleBag)
const isMobile = useIsMobile()
const bagExpanded = useBag((s) => s.bagExpanded)
return (
<Box
zIndex={{ sm: '3', md: '2' }}
width={{ sm: 'full', md: 'auto' }}
height={{ sm: 'full', md: 'auto' }}
position="fixed"
left={{ sm: '0', md: 'unset' }}
right={{ sm: 'unset', md: '0' }}
top={{ sm: '0', md: 'unset' }}
display={bagExpanded && isProfilePage ? 'flex' : 'none'}
>
<Suspense fallback={<Loader />}>
<Column
marginTop={{ sm: '0', md: '4' }}
marginRight={{ sm: '0', md: '20' }}
className={styles.tagContainer}
width={{ sm: 'full', md: '288' }}
height={{ sm: 'full', md: 'auto' }}
backgroundColor="backgroundSurface"
marginLeft="0"
justifyContent="flex-start"
>
{sellPageState === ProfilePageStateType.LISTING ? (
<ListingModal />
) : (
<>
<BagHeader bagQuantity={sellAssets.length} />
<Column
overflowX="hidden"
overflowY="auto"
position="relative"
paddingTop="6"
paddingBottom="6"
height="full"
className={styles.tagAssets}
>
{sellAssets.length
? sellAssets.map((asset, index) => <CartSellAssetRow asset={asset} key={index} />)
: null}
</Column>
<Box padding="12">
<Box
as="button"
className={`${buttonMedium} ${styles.orderButton}`}
disabled={sellAssets.length === 0}
onClick={() => {
isMobile && toggleCart()
setSellPageState(ProfilePageStateType.LISTING)
}}
>
Continue
</Box>
</Box>
</>
)}
</Column>
</Suspense>
</Box>
)
}
const BagHeader = ({ bagQuantity }: { bagQuantity: number }) => {
const toggleCart = useBag((state) => state.toggleBag)
const resetSellAssets = useSellAsset((state) => state.reset)
const isMobile = useIsMobile()
return (
<Box position="relative" zIndex="2" paddingTop="20" paddingLeft="12" paddingRight="12">
{isMobile ? (
<Box
as="button"
border="none"
color="textSecondary"
background="black"
className={styles.closeIcon}
onClick={toggleCart}
>
<CloseDropDownIcon />
</Box>
) : null}
<Box className={headlineSmall} paddingTop="0" paddingBottom="8" paddingX="0" margin="0">
{'Selected items'}
</Box>
{bagQuantity > 0 ? (
<Box className={bodySmall} paddingTop="0" paddingBottom="8" paddingX="0" marginY="0" marginX="auto">
{bagQuantity} {bagQuantity === 1 ? 'NFT' : 'NFTs'}
<Box as="span" position="relative" paddingRight="2" paddingLeft="4" style={{ fontSize: '8px', top: '-2px' }}>
&#x2022;
</Box>
<Box as="span" color="blue400" onClick={resetSellAssets} cursor="pointer" paddingLeft="2">
Remove all
</Box>
</Box>
) : null}
</Box>
)
}
export default Cart
import { Box } from 'nft/components/Box'
import { bodySmall, subheadSmall } from 'nft/css/common.css'
import { useSellAsset } from 'nft/hooks'
import { WalletAsset } from 'nft/types'
import { useEffect, useRef, useState } from 'react'
import * as styles from './TagAssetRow.css'
const CartSellAssetRow = ({ asset }: { asset: WalletAsset }) => {
const removeAsset = useSellAsset((state) => state.removeSellAsset)
const [hovered, setHovered] = useState(false)
const handleHover = () => setHovered(!hovered)
const assetRowRef = useRef<HTMLDivElement>()
useEffect(() => {
if (hovered && assetRowRef.current && assetRowRef.current.matches(':hover') === false) setHovered(false)
}, [hovered])
return (
<Box display="flex" padding="4" marginBottom="4" borderRadius="8" position="relative">
<Box
onMouseEnter={handleHover}
onMouseLeave={handleHover}
onClick={() => {
removeAsset(asset)
}}
>
<Box visibility={hovered ? 'visible' : 'hidden'} className={styles.removeAsset}>
<img className={styles.removeIcon} src={'/nft/svgs/minusCircle.svg'} alt="Remove item" />
</Box>
<img className={styles.tagAssetImage} src={asset.image_url} alt={asset.name} />
</Box>
<Box className={styles.tagAssetInfo}>
<Box className={`${subheadSmall} ${styles.tagAssetName}`}>{asset.name || `#${asset.tokenId}`}</Box>
<Box className={styles.tagAssetRowBottom}>
<Box className={`${bodySmall} ${styles.tagAssetCollectionName}`}>{asset.collection?.name}</Box>
</Box>
</Box>
</Box>
)
}
export default CartSellAssetRow
...@@ -25,7 +25,7 @@ export const headlineLarge = sprinkles({ fontWeight: 'normal', fontSize: '36', l ...@@ -25,7 +25,7 @@ export const headlineLarge = sprinkles({ fontWeight: 'normal', fontSize: '36', l
export const headlineMedium = sprinkles({ fontWeight: 'normal', fontSize: '28', lineHeight: '36' }) export const headlineMedium = sprinkles({ fontWeight: 'normal', fontSize: '28', lineHeight: '36' })
export const headlineSmall = sprinkles({ fontWeight: 'normal', fontSize: '20', lineHeight: '28' }) export const headlineSmall = sprinkles({ fontWeight: 'normal', fontSize: '20', lineHeight: '28' })
export const subhead = sprinkles({ fontWeight: 'medium', fontSize: '16', lineHeight: '16' }) 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' })
export const body = sprinkles({ fontWeight: 'normal', fontSize: '16', lineHeight: '24' }) export const body = sprinkles({ fontWeight: 'normal', fontSize: '16', lineHeight: '24' })
...@@ -37,7 +37,7 @@ export const buttonTextLarge = sprinkles({ fontWeight: 'semibold', fontSize: '20 ...@@ -37,7 +37,7 @@ export const buttonTextLarge = sprinkles({ fontWeight: 'semibold', fontSize: '20
export const buttonTextMedium = sprinkles({ fontWeight: 'semibold', fontSize: '16', lineHeight: '20' }) export const buttonTextMedium = sprinkles({ fontWeight: 'semibold', fontSize: '16', lineHeight: '20' })
export const buttonTextSmall = sprinkles({ fontWeight: 'semibold', fontSize: '14', lineHeight: '16' }) export const buttonTextSmall = sprinkles({ fontWeight: 'semibold', fontSize: '14', lineHeight: '16' })
const commonButtonStyles = style([ export const commonButtonStyles = style([
sprinkles({ sprinkles({
borderRadius: '12', borderRadius: '12',
transition: '250', transition: '250',
......
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