Skip to content

Commit 65dcade

Browse files
committed
integrated ui/ux feedback
1 parent ed34660 commit 65dcade

File tree

29 files changed

+517
-358
lines changed

29 files changed

+517
-358
lines changed

examples/react/src/components/Connected.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ export const Connected = () => {
507507
<Text className="mt-6" variant="small" color="muted" fontWeight="medium">
508508
Demos
509509
</Text>
510-
<CardButton title="Inventory" description="View all tokens in your wallet" onClick={() => setOpenWalletModal(true)} />
510+
<CardButton title="Wallet widget" description="View your integrated wallet" onClick={() => setOpenWalletModal(true)} />
511511
{(sponsoredContractAddresses[chainId] || networkForCurrentChainId.testnet) && isWaasConnectionActive && (
512512
<CardButton
513513
title="Send sponsored transaction"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { GearIcon, cn, cardVariants, Text } from '@0xsequence/design-system'
2+
import { useMemo, useState } from 'react'
3+
4+
import { FilterMenu } from './FilterMenu'
5+
import { AnimatePresence } from 'motion/react'
6+
import { useSettings } from '../../hooks'
7+
import { useWallets } from '@0xsequence/connect'
8+
9+
export const FilterButton = ({
10+
label,
11+
type
12+
}: {
13+
label: string
14+
type: 'tokens' | 'collectibles' | 'transactions' | 'bypassMenuWallets'
15+
}) => {
16+
const { wallets } = useWallets()
17+
const { selectedWallets, selectedNetworks, selectedCollections, allNetworks } = useSettings()
18+
const [isOpen, setIsOpen] = useState(false)
19+
20+
const howManyModifiedFilters = useMemo(() => {
21+
const isModifiedWallets = Number(selectedWallets.length !== wallets.length)
22+
const isModifiedNetworks = Number(selectedNetworks.length !== allNetworks.length)
23+
const isModifiedCollections = Number(selectedCollections.length !== 0)
24+
25+
return isModifiedWallets + isModifiedNetworks + isModifiedCollections
26+
}, [selectedWallets, wallets, selectedNetworks, allNetworks, selectedCollections])
27+
28+
return (
29+
<div
30+
className={cn(cardVariants({ clickable: true }), 'flex items-center justify-center p-2 relative')}
31+
style={{ height: '52px', width: '52px' }}
32+
onClick={() => setIsOpen(true)}
33+
>
34+
<GearIcon size="xl" color="white" />
35+
<div className="absolute top-0 right-0">
36+
{howManyModifiedFilters > 0 && (
37+
<div className="flex items-center justify-center w-6 h-6 rounded-full" style={{ backgroundColor: '#0076CC' }}>
38+
<Text variant="small" color="white">
39+
{howManyModifiedFilters}
40+
</Text>
41+
</div>
42+
)}
43+
</div>
44+
45+
<AnimatePresence>{isOpen && <FilterMenu onClose={() => setIsOpen(false)} label={label} type={type} />}</AnimatePresence>
46+
</div>
47+
)
48+
}

packages/wallet-widget/src/components/FilterMenu.tsx renamed to packages/wallet-widget/src/components/Filter/FilterMenu.tsx

Lines changed: 92 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { formatAddress, useWallets } from '@0xsequence/connect'
2-
import { cardVariants, ChevronRightIcon, cn, GradientAvatar, Text, TokenImage } from '@0xsequence/design-system'
1+
import { formatAddress, getNetwork, useWallets } from '@0xsequence/connect'
2+
import { Text, TokenImage } from '@0xsequence/design-system'
33
import { useGetTokenBalancesSummary } from '@0xsequence/hooks'
44
import { ContractType } from '@0xsequence/indexer'
5-
import { ChainId } from '@0xsequence/network'
65
import { useObservable } from 'micro-observables'
76
import { useState } from 'react'
87

9-
import { useSettings } from '../hooks'
10-
import { useFiatWalletsMap } from '../hooks/useFiatWalletsMap'
11-
import { getConnectorLogo } from '../utils/wallets'
8+
import { useSettings } from '../../hooks'
9+
import { useFiatWalletsMap } from '../../hooks/useFiatWalletsMap'
10+
import { getConnectorLogo } from '../../utils/wallets'
1211

13-
import { GradientAvatarList } from './GradientAvatarList'
14-
import { ListCardNav } from './ListCard'
15-
import { ListCardSelect } from './ListCard/ListCardSelect'
16-
import { SlideupDrawer } from './SlideupDrawer'
17-
import { WalletAccountGradient } from './WalletAccountGradient'
12+
import { ListCardNav } from '../ListCard'
13+
import { ListCardSelect } from '../ListCard/ListCardSelect'
14+
import { SlideupDrawer } from '../SlideupDrawer'
15+
import { WalletAccountGradient } from '../WalletAccountGradient'
16+
import { MediaIconWrapper, StackedIconTag } from '../IconWrappers'
17+
import { NetworkRow } from './NetworkRow'
1818

1919
enum FilterType {
2020
menu = 'Filters',
@@ -25,16 +25,12 @@ enum FilterType {
2525

2626
export const FilterMenu = ({
2727
label,
28-
buttonLabel,
2928
type,
30-
onClose,
31-
handleButtonPress
29+
onClose
3230
}: {
3331
label: string
34-
buttonLabel: string
3532
type: 'tokens' | 'collectibles' | 'transactions' | 'bypassMenuWallets'
3633
onClose: () => void
37-
handleButtonPress: () => void
3834
}) => {
3935
const { wallets } = useWallets()
4036
const {
@@ -79,22 +75,76 @@ export const FilterMenu = ({
7975
type === 'bypassMenuWallets' ? FilterType.wallets : FilterType.menu
8076
)
8177

82-
const walletsPreview = selectedWallets.length > 1 ? 'All' : <GradientAvatar address={selectedWallets[0].address} size="sm" />
78+
const walletsPreview =
79+
selectedWallets.length > 1 ? (
80+
<StackedIconTag
81+
iconList={[]}
82+
label={
83+
<Text variant="normal" color="primary">
84+
All
85+
</Text>
86+
}
87+
/>
88+
) : (
89+
<div className="flex flex-row gap-2 items-center">
90+
<StackedIconTag
91+
iconList={[selectedWallets[0].address]}
92+
isAccount
93+
label={
94+
<Text variant="normal" color="primary" nowrap style={{ maxWidth: '200px' }} ellipsis>
95+
{formatAddress(selectedWallets[0].address)}
96+
</Text>
97+
}
98+
/>
99+
</div>
100+
)
83101

84102
const networksPreview =
85103
selectedNetworks.length > 1 ? (
86-
'All'
104+
<div className="flex flex-row gap-2 items-center">
105+
<StackedIconTag
106+
iconList={[]}
107+
label={
108+
<Text variant="normal" color="primary">
109+
All
110+
</Text>
111+
}
112+
/>
113+
</div>
87114
) : (
88-
<TokenImage src={`https://assets.sequence.info/images/networks/medium/${selectedNetworks[0]}.webp`} />
115+
<StackedIconTag
116+
iconList={[`https://assets.sequence.info/images/networks/medium/${selectedNetworks[0]}.webp`]}
117+
label={
118+
<Text variant="normal" color="primary" nowrap style={{ maxWidth: '200px' }} ellipsis>
119+
{getNetwork(selectedNetworks[0]).title}
120+
</Text>
121+
}
122+
/>
89123
)
90124

91125
const collectionsPreview =
92126
collections?.length === 0 ? (
93-
'N/A'
127+
<Text variant="normal" color="primary">
128+
N/A
129+
</Text>
94130
) : selectedCollections.length === 0 ? (
95-
'All'
131+
<StackedIconTag
132+
iconList={[]}
133+
label={
134+
<Text variant="normal" color="primary">
135+
All
136+
</Text>
137+
}
138+
/>
96139
) : (
97-
<TokenImage src={selectedCollections[0].contractInfo?.logoURI} symbol={selectedCollections[0].contractInfo?.name} />
140+
<StackedIconTag
141+
iconList={[selectedCollections[0].contractInfo?.logoURI]}
142+
label={
143+
<Text variant="normal" color="primary" nowrap style={{ maxWidth: '200px' }} ellipsis>
144+
{selectedCollections[0].contractInfo?.name}
145+
</Text>
146+
}
147+
/>
98148
)
99149

100150
const handleFilterChange = (filter: FilterType) => {
@@ -105,56 +155,41 @@ export const FilterMenu = ({
105155
<SlideupDrawer
106156
onClose={onClose}
107157
label={selectedFilter === FilterType.menu ? label : selectedFilter}
108-
buttonLabel={buttonLabel}
109-
handleButtonPress={handleButtonPress}
110158
onBackPress={
111159
type !== 'bypassMenuWallets' && selectedFilter !== FilterType.menu ? () => handleFilterChange(FilterType.menu) : undefined
112160
}
113161
>
114162
{selectedFilter === FilterType.menu ? (
115163
<div className="flex flex-col bg-background-primary gap-3">
116164
<ListCardNav
117-
rightChildren={
118-
<Text color="primary" fontWeight="medium" variant="normal">
119-
{walletsPreview}
120-
</Text>
121-
}
122-
style={{ height: '60px' }}
165+
rightChildren={walletsPreview}
166+
style={{ height: '64px' }}
123167
onClick={() => handleFilterChange(FilterType.wallets)}
124168
>
125169
<Text color="primary" fontWeight="medium" variant="normal">
126170
Wallets
127171
</Text>
128172
</ListCardNav>
129173
<ListCardNav
130-
rightChildren={
131-
<Text color="primary" fontWeight="medium" variant="normal">
132-
{networksPreview}
133-
</Text>
134-
}
135-
style={{ height: '60px' }}
174+
rightChildren={networksPreview}
175+
style={{ height: '64px' }}
136176
onClick={() => handleFilterChange(FilterType.networks)}
137177
>
138178
<Text color="primary" fontWeight="medium" variant="normal">
139179
Networks
140180
</Text>
141181
</ListCardNav>
142182
{type === 'collectibles' && (
143-
<div
144-
className={cn(cardVariants({ clickable: true }), 'flex flex-row justify-between items-center')}
145-
style={{ height: '60px' }}
146-
onClick={collections?.length ? () => handleFilterChange(FilterType.collections) : undefined}
183+
<ListCardNav
184+
rightChildren={collectionsPreview}
185+
style={{ height: '64px' }}
186+
disabled={collections?.length === 0}
187+
onClick={() => handleFilterChange(FilterType.collections)}
147188
>
148189
<Text color="primary" fontWeight="medium" variant="normal">
149190
Collections
150191
</Text>
151-
<div className="flex flex-row items-center gap-2">
152-
<Text color="primary" fontWeight="medium" variant="normal">
153-
{collectionsPreview}
154-
</Text>
155-
<ChevronRightIcon color="white" />
156-
</div>
157-
</div>
192+
</ListCardNav>
158193
)}
159194
</div>
160195
) : selectedFilter === FilterType.wallets ? (
@@ -171,7 +206,7 @@ export const FilterMenu = ({
171206
}
172207
onClick={() => setSelectedWallets([])}
173208
>
174-
<GradientAvatarList accountAddressList={wallets.map(wallet => wallet.address)} size="md" />
209+
<MediaIconWrapper iconList={wallets.map(wallet => wallet.address)} size="sm" isAccount />
175210
<Text color="primary" fontWeight="medium" variant="normal">
176211
All
177212
</Text>
@@ -211,24 +246,22 @@ export const FilterMenu = ({
211246
isSelected={selectedNetworksObservable.get().length > 1}
212247
onClick={() => setSelectedNetworks([])}
213248
>
249+
<MediaIconWrapper
250+
iconList={allNetworks.map(network => `https://assets.sequence.info/images/networks/medium/${network}.webp`)}
251+
size="sm"
252+
/>
214253
<Text color="primary" fontWeight="medium" variant="normal">
215254
All
216255
</Text>
217256
</ListCardSelect>
218257
)}
219258
{allNetworks.map(chainId => (
220-
<ListCardSelect
259+
<NetworkRow
221260
key={chainId}
261+
chainId={chainId}
222262
isSelected={selectedNetworksObservable.get().length === 1 && selectedNetworksObservable.get().includes(chainId)}
223263
onClick={() => setSelectedNetworks([chainId])}
224-
>
225-
<div className="flex gap-2 justify-center items-center">
226-
<TokenImage src={`https://assets.sequence.info/images/networks/medium/${chainId}.webp`} />
227-
<Text color="primary" variant="normal" fontWeight="bold">
228-
{ChainId[chainId]}
229-
</Text>
230-
</div>
231-
</ListCardSelect>
264+
/>
232265
))}
233266
</div>
234267
) : selectedFilter === FilterType.collections ? (
@@ -239,6 +272,7 @@ export const FilterMenu = ({
239272
isSelected={selectedCollectionsObservable.get().length === 0}
240273
onClick={() => setSelectedCollections([])}
241274
>
275+
<MediaIconWrapper iconList={collections.map(collection => collection.contractInfo?.logoURI)} size="sm" />
242276
<Text color="primary" fontWeight="medium" variant="normal">
243277
All
244278
</Text>
@@ -251,7 +285,7 @@ export const FilterMenu = ({
251285
selectedCollectionsObservable.get().find(c => c.contractAddress === collection.contractAddress) !== undefined ||
252286
collections.length === 1
253287
}
254-
onClick={() => setSelectedCollections([collection])}
288+
onClick={collections.length > 1 ? () => setSelectedCollections([collection]) : undefined}
255289
>
256290
<TokenImage src={collection.contractInfo?.logoURI} symbol={collection.contractInfo?.name} />
257291
<Text color="primary" fontWeight="medium" variant="normal">
@@ -264,6 +298,3 @@ export const FilterMenu = ({
264298
</SlideupDrawer>
265299
)
266300
}
267-
268-
// TODO: swap out collectionsPreview with home screen icons later
269-
// TODO: add icons to networks
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { TokenImage, Text } from '@0xsequence/design-system'
2+
import { ListCardSelect } from '../ListCard'
3+
import { getNetwork } from '@0xsequence/connect'
4+
5+
export const NetworkRow = ({ chainId, isSelected, onClick }: { chainId: number; isSelected: boolean; onClick: () => void }) => {
6+
const network = getNetwork(chainId)
7+
const isTestnet = network.testnet
8+
const title = network.title
9+
return (
10+
<ListCardSelect key={chainId} isSelected={isSelected} onClick={onClick}>
11+
<div className="flex gap-2 justify-center items-center relative">
12+
{isTestnet && (
13+
<div
14+
className="absolute z-1 border rounded-full"
15+
style={{
16+
width: '10px',
17+
height: '10px',
18+
left: '-1px',
19+
top: '-1px',
20+
backgroundColor: '#F4B03E'
21+
}}
22+
/>
23+
)}
24+
<TokenImage src={`https://assets.sequence.info/images/networks/medium/${chainId}.webp`} />
25+
<Text color="primary" variant="normal" fontWeight="bold">
26+
{title}
27+
</Text>
28+
</div>
29+
</ListCardSelect>
30+
)
31+
}

0 commit comments

Comments
 (0)