Skip to content

Commit

Permalink
feat: group connectors between native and external (#271)
Browse files Browse the repository at this point in the history
Co-authored-by: luizstacio <luizstacio@gmail.com>
Co-authored-by: Hélcio Franco <github@helciofranco.com>
  • Loading branch information
3 people authored Sep 23, 2024
1 parent 0fbc99b commit 366ffa9
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-games-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuels/react": patch
---

Group connectors between native and external
1 change: 1 addition & 0 deletions packages/bako-safe/src/BakoSafeConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class BakoSafeConnector extends FuelConnector {
};
installed = true;
connected = false;
external = false;

events = {
...BakoSafeConnectorEvents,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class BurnerWalletConnector extends FuelConnector {

connected = false;
installed = true;
external = false;

events = FuelConnectorEventTypes;

Expand Down
1 change: 1 addition & 0 deletions packages/common/src/PredicateConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {
export abstract class PredicateConnector extends FuelConnector {
public connected = false;
public installed = false;
external = true;
public events = FuelConnectorEventTypes;
protected predicateAddress!: string;
protected customPredicate: Maybe<PredicateConfig>;
Expand Down
1 change: 1 addition & 0 deletions packages/fuel-wallet/src/FuelWalletConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class FuelWalletConnector extends FuelConnector {
name = '';
connected = false;
installed = false;
external = false;
events = FuelConnectorEventTypes;
metadata: ConnectorMetadata = {
image: '/connectors/fuel-wallet.svg',
Expand Down
5 changes: 2 additions & 3 deletions packages/react/src/providers/FuelUIProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { useConnectors } from '../hooks/useConnectors';

import { NATIVE_CONNECTORS } from '../config';
import { useAccount, useBalance } from '../hooks';
import { BADGE_BLACKLIST } from '../ui/Connect/components/Connectors/ConnectorBadge';
import { useFuel } from './FuelHooksProvider';

export type FuelUIProviderProps = {
Expand Down Expand Up @@ -82,8 +81,8 @@ const sortConnectors = (connectors: FuelConnector[]): FuelConnector[] => {
}

// Use temporary variables to represent "installed" status for sorting
const aInstalled = !BADGE_BLACKLIST.includes(a.name) && a.installed;
const bInstalled = !BADGE_BLACKLIST.includes(b.name) && b.installed;
const aInstalled = NATIVE_CONNECTORS.includes(a.name) && a.installed;
const bInstalled = NATIVE_CONNECTORS.includes(b.name) && b.installed;
if (aInstalled !== bInstalled) {
return aInstalled ? -1 : 1;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { FuelConnector } from 'fuels';
import { useMemo } from 'react';
import { NATIVE_CONNECTORS } from '../../../../config';
import { BadgeInfo, BadgeSuccess } from './styles';

interface ConnectorBadgeProps {
Expand All @@ -8,18 +9,13 @@ interface ConnectorBadgeProps {
installed: FuelConnector['installed'];
}

// We don't want to show the INSTALLED badge for these connectors
// Because we don't know exactly if externally they are installed or not
// These, for example, are using WalletConnect as a provider
export const BADGE_BLACKLIST = ['Ethereum Wallets', 'Solana Wallets'];

export function ConnectorBadge({
name,
connected,
installed,
}: ConnectorBadgeProps) {
const isBlacklisted = useMemo<boolean>(() => {
return BADGE_BLACKLIST.includes(name);
return !NATIVE_CONNECTORS.includes(name);
}, [name]);

if (connected) {
Expand Down
112 changes: 84 additions & 28 deletions packages/react/src/ui/Connect/components/Connectors/Connectors.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,54 @@
import { useConnectUI } from '../../../../providers/FuelUIProvider';
import { useMemo, useState } from 'react';
import {
type FuelUIContextType,
useConnectUI,
} from '../../../../providers/FuelUIProvider';
import { ConnectorIcon } from '../ConnectorIcon';
import { ConnectorBadge } from './ConnectorBadge';

import type { FuelConnector } from 'fuels';
import { NATIVE_CONNECTORS } from '../../../../config';
import { ConnectorsLoader } from './ConnectorsLoader';
import { ConnectorItem, ConnectorList, ConnectorName } from './styles';
import {
ConnectorItem,
ConnectorList,
ConnectorName,
GroupFirstTitleContainer,
GroupLastTitle,
GroupLastTitleContainer,
} from './styles';

const renderConnector = (
connect: FuelUIContextType['dialog']['connect'],
theme: FuelUIContextType['theme'],
connector: FuelConnector,
index: number,
) => (
<ConnectorItem
tabIndex={index + 1}
key={connector.name}
aria-label={`Connect to ${connector.name}`}
data-installed={connector.installed}
data-connected={connector.connected}
onClick={(e) => {
e.preventDefault();
connect(connector);
}}
>
<ConnectorIcon
connectorMetadata={connector.metadata}
connectorName={connector.name}
size={32}
theme={theme}
/>
<ConnectorName>{connector.name}</ConnectorName>
<ConnectorBadge
name={connector.name}
connected={connector.connected}
installed={connector.installed}
/>
</ConnectorItem>
);

export function Connectors() {
const {
Expand All @@ -14,34 +59,45 @@ export function Connectors() {
dialog: { connect },
} = useConnectUI();

const [renderConnectorItem] = useState(() =>
renderConnector.bind(null, connect, theme),
);

const { native, external } = useMemo(
() =>
connectors.reduce(
(acc, curr) => {
const array = NATIVE_CONNECTORS.includes(curr.name)
? acc.native
: acc.external;
array.push(curr);

return acc;
},
{
native: [] as Array<FuelConnector>,
external: [] as Array<FuelConnector>,
},
),
[connectors],
);

const shouldTitleGroups = !isLoading && !!native.length && !!external.length;

return (
<ConnectorList>
{connectors.map((connector, index) => (
<ConnectorItem
tabIndex={index + 1}
key={connector.name}
aria-label={`Connect to ${connector.name}`}
data-installed={connector.installed}
data-connected={connector.connected}
onClick={(e) => {
e.preventDefault();
connect(connector);
}}
>
<ConnectorIcon
connectorMetadata={connector.metadata}
connectorName={connector.name}
size={32}
theme={theme}
/>
<ConnectorName>{connector.name}</ConnectorName>
<ConnectorBadge
name={connector.name}
connected={connector.connected}
installed={connector.installed}
/>
</ConnectorItem>
))}
{shouldTitleGroups && (
<GroupFirstTitleContainer>
<GroupLastTitle>Fuel Native Wallets</GroupLastTitle>
</GroupFirstTitleContainer>
)}
{!isLoading && native.map(renderConnectorItem)}
{shouldTitleGroups && (
<GroupLastTitleContainer>
<GroupLastTitle>Non-Native Wallets</GroupLastTitle>
</GroupLastTitleContainer>
)}
{!isLoading && external.map(renderConnectorItem)}
{isLoading && (
<ConnectorsLoader items={fuelConfig.connectors?.length || 2} />
)}
Expand Down
31 changes: 31 additions & 0 deletions packages/react/src/ui/Connect/components/Connectors/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const ConnectorList = styled.div`
align-items: center;
gap: var(--fuel-items-gap);
padding: 0px 14px;
margin-top: 23px;
`;

export const ConnectorName = styled.div`
Expand Down Expand Up @@ -56,3 +57,33 @@ export const BadgeSuccess = styled(Badge)`;
background-color: var(--fuel-green-3);
color: var(--fuel-green-11);
`;

export const GroupLastTitle = styled.p`
color: #797979;
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: 20px;
letter-spacing: -0.13px;
`;

export const GroupFirstTitleContainer = styled.div`
display: flex;
align-items: center;
gap: 4px;
justify-content: flex-start;
width: 100%;
padding-left: 3px;
margin-bottom: 7px;
`;

export const GroupLastTitleContainer = styled.div`
display: flex;
align-items: center;
gap: 4px;
justify-content: flex-start;
width: 100%;
padding-left: 3px;
margin: 14px 0px 7px 0px;
`;
45 changes: 45 additions & 0 deletions packages/react/src/ui/Connect/icons/InfoCircleIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { SvgIconProps } from '../../../ui/types';

export function InfoCircleIcon({
theme,
size,
stroke = '#797979',
...props
}: SvgIconProps & { stroke?: string }) {
return (
<svg
width={size}
height={size}
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<title>Info Circle Icon</title>
<g clip-path="url(#clip0_2341_25997)">
<path
d="M5.375 5.5H6L6 8.125M10.625 6C10.625 8.55432 8.55432 10.625 6 10.625C3.44568 10.625 1.375 8.55432 1.375 6C1.375 3.44568 3.44568 1.375 6 1.375C8.55432 1.375 10.625 3.44568 10.625 6Z"
stroke={stroke}
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
<rect
x="5.625"
y="3.625"
width="0.75"
height="0.75"
rx="0.375"
fill={stroke}
stroke={stroke}
stroke-width="0.25"
/>
</g>
<defs>
<clipPath id="clip0_2341_25997">
<rect width="12" height="12" fill="white" />
</clipPath>
</defs>
</svg>
);
}

0 comments on commit 366ffa9

Please sign in to comment.