Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enforce target network #285

Merged
merged 36 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
594a5f2
feat: move global styling to HOC
arthurgeron Sep 23, 2024
a59f610
feat: create useConnectorNetwork hook
arthurgeron Sep 24, 2024
4ec5a98
chore: remove import of moved file
arthurgeron Sep 24, 2024
730ec74
fix: theme not loading properly
arthurgeron Sep 24, 2024
8ec2920
fix: type error
arthurgeron Sep 24, 2024
37402f3
revert: useConnectorNetwork
arthurgeron Sep 24, 2024
4baa0ba
feat: fuel chain provider
arthurgeron Sep 24, 2024
4253b83
feat: move icons to shared folder
arthurgeron Sep 24, 2024
5183986
feat: define default teme in hoc
arthurgeron Sep 24, 2024
8d264f8
feat: move spinner icon
arthurgeron Sep 24, 2024
bd313e9
feat: create NetworkMonitor dialog
arthurgeron Sep 24, 2024
1d5f79a
feat: add optional monitor network to providers
arthurgeron Sep 24, 2024
1735368
feat: enable network monitor on example
arthurgeron Sep 24, 2024
0eb4893
chore: changeset
arthurgeron Sep 24, 2024
a8f16b0
feat: optional enforcement of chainId via FuelProvider
arthurgeron Sep 24, 2024
89096e8
fix: show gray button when disabled
arthurgeron Sep 24, 2024
1bc00bf
fix: missing SvgIconProps type
arthurgeron Sep 24, 2024
047c65a
feat: add light gray to theme
arthurgeron Sep 24, 2024
4fe5631
chore: adjust description of provider
arthurgeron Sep 24, 2024
de8ef90
feat: design adjustments
arthurgeron Sep 24, 2024
eda1f51
Merge branch 'main' into ag/feat/select-network
arthurgeron Sep 24, 2024
6f7a89d
fix: not closing on disconnect
arthurgeron Sep 24, 2024
eab0a10
fix: dialog content clipping in mobile devices
arthurgeron Sep 24, 2024
bd3a1cb
chore: adjust margins
arthurgeron Sep 24, 2024
a87320f
chore: adjust disconnect button style
arthurgeron Sep 24, 2024
69447e4
feat: consistent margins
arthurgeron Sep 24, 2024
1267e5d
chore: use less technical words in dialog
arthurgeron Sep 24, 2024
2622345
chore: make separator color blend with background
arthurgeron Sep 24, 2024
6e47ae3
Merge branch 'main' into ag/feat/select-network
arthurgeron Sep 24, 2024
cfa5f36
fix: wrong condition caused by biome autofix
arthurgeron Sep 24, 2024
c6bbbd0
Merge branch 'ag/feat/select-network' of github.com:FuelLabs/fuel-con…
arthurgeron Sep 24, 2024
5606bf5
feat: apply same padding as connect modal
arthurgeron Sep 24, 2024
44e5ed1
feat: disable closing dialog when clicking outside or escape
arthurgeron Sep 24, 2024
31a4081
fix: when wallet switchs to correct network
arthurgeron Sep 24, 2024
12f559c
chore: remove unused query key
arthurgeron Sep 24, 2024
2e46ea9
chore: close if data not valid
arthurgeron Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/happy-snakes-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuels/react": minor
---

Add FuelChainProvider
5 changes: 5 additions & 0 deletions .changeset/shiny-coats-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuels/react": patch
---

Moved icons and global stylings to HOC
1 change: 1 addition & 0 deletions examples/react-app/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<QueryClientProvider client={queryClient}>
<FuelProvider
theme="dark"
chainId={0}
fuelConfig={{
connectors: defaultConnectors({
devMode: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const lightTheme = {
'--fuel-green-11': '#008347',
'--fuel-blue-3': '#E6F4FE',
'--fuel-blue-11': '#0D74CE',
'--fuel-color-light-gray': 'rgb(83 79 79 / 84%)',
'--fuel-separator-color': 'rgb(83 79 79 / 13%)',
};

const darkTheme = {
Expand All @@ -50,6 +52,8 @@ const darkTheme = {
'--fuel-green-11': '#00DD75',
'--fuel-blue-3': '#0D2847',
'--fuel-blue-11': '#70B9FF',
'--fuel-color-light-gray': 'rgb(165 165 165 / 84%)',
'--fuel-separator-color': 'rgb(165 165 165 / 13%)',
};

type CustomTheme = Partial<typeof commonTheme & typeof lightTheme>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../types';
import type { SvgIconProps } from '../types';

export function BackIcon({ size, ...props }: SvgIconProps) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../../ui/types';
import type { SvgIconProps } from '../types';

export function CloseIcon({ size, ...props }: SvgIconProps) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../types';
import type { SvgIconProps } from '../types';

export function FuelWalletDevelopmentIcon({ size, ...props }: SvgIconProps) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../types';
import type { SvgIconProps } from '../types';

export function FuelWalletIcon({ size, ...props }: SvgIconProps) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../../ui/types';
import type { SvgIconProps } from '../types';

export function FueletIcon({ theme, size, ...props }: SvgIconProps) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../../ui/types';
import type { SvgIconProps } from '../types';

export function InfoCircleIcon({
theme,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SvgIconProps } from '../../types';
import type { SvgIconProps } from '../types';

export function NoFundIcon({ size, ...props }: SvgIconProps) {
return (
Expand Down
24 changes: 24 additions & 0 deletions packages/react/src/providers/FuelChainProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Network } from 'fuels';
import { createContext, useContext } from 'react';

const context = createContext<Network['chainId'] | null | undefined>(null);

/**
* A hook that returns the target chain id to be enforced on the active provider.
*
* @examples
* ```ts
* const { chainId } = useFuelChain();
* console.log(chainId);
* ```
*/
export function useFuelChain() {
const contextData = useContext(context);

if (contextData === null) {
throw new Error('useFuelChain must be used within a FuelChainProvider');
}
return { chainId: contextData };
}

export const FuelChainProvider = context.Provider;
32 changes: 22 additions & 10 deletions packages/react/src/providers/FuelProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import type { FuelConfig } from 'fuels';

import { Connect } from '../ui/Connect';

import { FuelHooksProvider } from './FuelHooksProvider';
import { FuelChainProvider } from '../providers/FuelChainProvider';
import { NetworkMonitor } from '../ui/NetworkMonitor';
import { FuelHooksProvider, useFuel } from './FuelHooksProvider';
import { FuelUIProvider, type FuelUIProviderProps } from './FuelUIProvider';

export { useFuel } from './FuelHooksProvider';
Expand All @@ -11,26 +13,36 @@ export { useConnectUI } from './FuelUIProvider';
type FuelProviderProps = {
ui?: boolean;
fuelConfig?: FuelConfig;
/**
* Whether enforce connectors to be on the desired the network.
* @default true
*/
chainId?: number;
} & FuelUIProviderProps;

export function FuelProvider({
theme,
theme: _theme,
children,
fuelConfig,
bridgeURL,
ui = true,
chainId,
}: FuelProviderProps) {
const theme = _theme || 'light';
if (ui) {
return (
<FuelHooksProvider fuelConfig={fuelConfig}>
<FuelUIProvider
theme={theme}
bridgeURL={bridgeURL}
fuelConfig={fuelConfig}
>
<Connect />
{children}
</FuelUIProvider>
<FuelChainProvider value={chainId ?? undefined}>
<FuelUIProvider
theme={theme}
bridgeURL={bridgeURL}
fuelConfig={fuelConfig}
>
<Connect />
{chainId != null && <NetworkMonitor theme={theme} />}
{children}
</FuelUIProvider>
</FuelChainProvider>
</FuelHooksProvider>
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/providers/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './FuelProvider';
export * from './FuelChainProvider';
7 changes: 7 additions & 0 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ export type Connector = {
installed: boolean;
};

export type SvgIconProps = {
theme?: string;
className?: string;
onClick?: () => void;
size: number;
};

export type ConnectorList = Array<Connector>;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { BRIDGE_URL } from '../../../../config';
import { NoFundIcon } from '../../../../icons/NoFundIcon';
import { useConnectUI } from '../../../../providers/FuelUIProvider';
import { NoFundIcon } from '../../icons/NoFundIcon';
import {
ConnectorButton,
ConnectorButtonPrimary,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FuelConnector } from 'fuels';
import { useConnectUI } from '../../../../providers/FuelUIProvider';
import { ConnectorIcon } from '../ConnectorIcon';

import { Spinner } from '../Spinner/Spinner';
import { Spinner } from '../../../../icons/Spinner';
import {
ConnectorButton,
ConnectorButtonPrimary,
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/ui/Connect/components/ConnectorIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ConnectorMetadata } from 'fuels';

import type { SvgIconProps } from '../../types';
import { FuelWalletDevelopmentIcon } from '../icons/FuelWalletDevelopmentIcon';
import { FuelWalletIcon } from '../icons/FuelWalletIcon';
import { FueletIcon } from '../icons/FueletIcon';
import { FuelWalletDevelopmentIcon } from '../../../icons/FuelWalletDevelopmentIcon';
import { FuelWalletIcon } from '../../../icons/FuelWalletIcon';
import { FueletIcon } from '../../../icons/FueletIcon';
import type { SvgIconProps } from '../../../types';
import { getImageUrl } from '../utils/getImageUrl';

type ConnectorIconProps = {
Expand Down
5 changes: 2 additions & 3 deletions packages/react/src/ui/Connect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ import { Connectors } from './components/Connectors';
import {
BackIcon,
CloseIcon,
DialogContent,
DialogMain,
DialogOverlay,
DialogTitle,
Divider,
FuelRoot,
} from './styles';
import { getThemeVariables } from './themes';

import './index.css';
import type { FuelConnector } from 'fuels';
import { getThemeVariables } from '../../constants/themes';
import { DialogContent } from '../Dialog/components/Content';
import { Bridge } from './components/Bridge/Bridge';
import { Connecting } from './components/Connector/Connecting';
import { ExternalDisclaimer } from './components/ExternalDisclaimer/ExternalDisclaimer';
Expand Down
52 changes: 2 additions & 50 deletions packages/react/src/ui/Connect/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as Dialog from '@radix-ui/react-dialog';
import { keyframes, styled } from 'styled-components';

import { BackIcon as CBackIcon } from './icons/BackIcon';
import { CloseIcon as CCloseIcon } from './icons/CloseIcon';
import { BackIcon as CBackIcon } from '../../icons/BackIcon';
import { CloseIcon as CCloseIcon } from '../../icons/CloseIcon';

const overlayShow = keyframes`
from {
Expand All @@ -13,17 +13,6 @@ const overlayShow = keyframes`
}
`;

const contentShow = keyframes`
from {
opacity: 0;
transform: translate(-50%, -48%) scale(0.96);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
`;

const placeholderLoader = keyframes`
0%{
background-position: -468px 0
Expand All @@ -40,43 +29,6 @@ export const DialogOverlay = styled(Dialog.Overlay)`
animation: ${overlayShow} 150ms cubic-bezier(0.16, 1, 0.3, 1);
`;

export const DialogContent = styled(Dialog.Content)`
overflow: hidden;
color: var(--fuel-color);
user-select: none;
max-height: calc(100% - 20px);
box-sizing: border-box;
background-color: var(--fuel-dialog-background);
position: fixed;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 36px;
padding: 14px 0px;
padding-bottom: 18px;
animation: ${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1);
box-shadow:
hsl(206 22% 7% / 35%) 0px 10px 38px -10px,
hsl(206 22% 7% / 20%) 0px 10px 20px -15px;

&:focus {
outline: none;
}

@media (min-width: 431px) {
top: 50%;
width: 360px;
max-width: calc(100% - 20px);
}

@media (max-width: 430px) {
top: auto;
bottom: -246px;
width: 100vw;
max-width: 100%;
border-radius: 36px 36px 0 0;
}
` as unknown as typeof Dialog.Content;

export const DialogTitle = styled(Dialog.Title)`
padding: 8px 14px 12px;
margin: 0;
Expand Down
45 changes: 45 additions & 0 deletions packages/react/src/ui/Dialog/components/Content/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as Dialog from '@radix-ui/react-dialog';
import { keyframes, styled } from 'styled-components';

const contentShow = keyframes`
from {
opacity: 0;
transform: translate(-50%, -48%) scale(0.96);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
`;

export const DialogContent = styled(Dialog.Content)`
overflow: hidden;
color: var(--fuel-color);
user-select: none;
max-height: calc(100% - 20px);
box-sizing: border-box;
background-color: var(--fuel-dialog-background);
position: fixed;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 36px;
padding: 14px 0px;
padding-bottom: 18px;
animation: ${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1);
top: 50%;
width: 360px;
max-width: calc(100% - 20px);
box-shadow:
hsl(206 22% 7% / 35%) 0px 10px 38px -10px,
hsl(206 22% 7% / 20%) 0px 10px 20px -15px;

&:focus {
outline: none;
}

@media (max-width: 430px) {
top: 50%;
width: 100%;
border-radius: 36px;
}
` as unknown as typeof Dialog.Content;
Loading
Loading