From e3538818f76e9716d3211c2c32a24bf511c3b9fa Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 11 Sep 2024 16:14:02 -0700 Subject: [PATCH] add rpc url and block explorer modals --- .../multichain/multichain-components.scss | 3 + .../add-block-explorer-modal.tsx | 91 +++++++++++++++ .../add-block-explorer-modal/index.scss | 9 ++ .../add-rpc-url-modal.test.tsx.snap | 76 +++++++++---- .../add-rpc-url-modal.test.tsx | 12 +- .../add-rpc-url-modal/add-rpc-url-modal.tsx | 107 ++++++++++++++---- .../add-rpc-url-modal/index.scss | 9 ++ 7 files changed, 257 insertions(+), 50 deletions(-) create mode 100644 ui/components/multichain/network-list-menu/add-block-explorer-modal/add-block-explorer-modal.tsx create mode 100644 ui/components/multichain/network-list-menu/add-block-explorer-modal/index.scss create mode 100644 ui/components/multichain/network-list-menu/add-rpc-url-modal/index.scss diff --git a/ui/components/multichain/multichain-components.scss b/ui/components/multichain/multichain-components.scss index 5fda42a8141f..5f9a7dc65d4b 100644 --- a/ui/components/multichain/multichain-components.scss +++ b/ui/components/multichain/multichain-components.scss @@ -18,9 +18,12 @@ @import 'connected-accounts-menu'; @import 'connected-site-menu'; @import 'create-named-snap-account'; +@import 'dropdown-editor'; @import 'token-list-item'; @import 'network-list-item'; @import 'network-list-item-menu'; +@import 'network-list-menu/add-rpc-url-modal'; +@import 'network-list-menu/add-block-explorer-modal'; @import 'network-list-menu'; @import 'product-tour-popover'; @import 'nft-item'; diff --git a/ui/components/multichain/network-list-menu/add-block-explorer-modal/add-block-explorer-modal.tsx b/ui/components/multichain/network-list-menu/add-block-explorer-modal/add-block-explorer-modal.tsx new file mode 100644 index 000000000000..65b98b081921 --- /dev/null +++ b/ui/components/multichain/network-list-menu/add-block-explorer-modal/add-block-explorer-modal.tsx @@ -0,0 +1,91 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + ButtonPrimary, + ButtonPrimarySize, + FormTextField, + FormTextFieldSize, + HelpText, + HelpTextSeverity, +} from '../../../component-library'; +import { + BackgroundColor, + BlockSize, + BorderRadius, + Display, + FlexDirection, + JustifyContent, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { isWebUrl } from '../../../../../app/scripts/lib/util'; + +const AddBlockExplorerModal = ({ + onAdded, +}: { + onAdded: (url: string) => void; +}) => { + const t = useI18nContext(); + const [url, setUrl] = useState(); + const [error, setError] = useState(); + + useEffect(() => { + if (url && url?.length > 0 && !isWebUrl(url)) { + setError(t('urlErrorMsg')); + } else { + setError(undefined); + } + }, [url]); + + return ( + + + setUrl(e.target.value)} + /> + {error && ( + {error} + )} + + + { + if (url) { + onAdded(url); + } + }} + > + {t('addUrl')} + + + + ); +}; + +export default AddBlockExplorerModal; diff --git a/ui/components/multichain/network-list-menu/add-block-explorer-modal/index.scss b/ui/components/multichain/network-list-menu/add-block-explorer-modal/index.scss new file mode 100644 index 000000000000..196db3e6a48e --- /dev/null +++ b/ui/components/multichain/network-list-menu/add-block-explorer-modal/index.scss @@ -0,0 +1,9 @@ +.add-block-explorer-modal { + overflow-y: auto; + + &__footer { + position: sticky; + bottom: 0; + box-shadow: 0 0 8px 0 var(--color-shadow-default); + } +} diff --git a/ui/components/multichain/network-list-menu/add-rpc-url-modal/__snapshots__/add-rpc-url-modal.test.tsx.snap b/ui/components/multichain/network-list-menu/add-rpc-url-modal/__snapshots__/add-rpc-url-modal.test.tsx.snap index 0fa9ff26c6ff..6f151cfe0c0e 100644 --- a/ui/components/multichain/network-list-menu/add-rpc-url-modal/__snapshots__/add-rpc-url-modal.test.tsx.snap +++ b/ui/components/multichain/network-list-menu/add-rpc-url-modal/__snapshots__/add-rpc-url-modal.test.tsx.snap @@ -3,36 +3,70 @@ exports[`AddRpcUrlModal should render correctly 1`] = `
- + +
+ +
+
- + +
+ +
- + +
`; diff --git a/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.test.tsx b/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.test.tsx index 65b8e889e94b..510ca7d98f05 100644 --- a/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.test.tsx +++ b/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.test.tsx @@ -17,25 +17,19 @@ describe('AddRpcUrlModal', () => { }); it('should render correctly', () => { - const { container } = render(); + const { container } = render( undefined} />); expect(container).toMatchSnapshot(); }); - it('should render the input field with the correct label', () => { - render(); - const inputLabel = screen.getByLabelText('additionalRpcUrl'); - expect(inputLabel).toBeInTheDocument(); - }); - it('should render the "Add URL" button with correct text', () => { - render(); + render( undefined} />); const addButton = screen.getByRole('button', { name: 'addUrl' }); expect(addButton).toBeInTheDocument(); }); it('should call the appropriate function when "Add URL" button is clicked', () => { const mockAddUrl = jest.fn(); - render(); + render( null} />); const addButton = screen.getByRole('button', { name: 'addUrl' }); userEvent.click(addButton); expect(mockAddUrl).not.toHaveBeenCalled(); diff --git a/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.tsx b/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.tsx index 8a9ff53a74b5..b2086aeab2f5 100644 --- a/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.tsx +++ b/ui/components/multichain/network-list-menu/add-rpc-url-modal/add-rpc-url-modal.tsx @@ -1,42 +1,109 @@ -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Box, ButtonPrimary, ButtonPrimarySize, FormTextField, + FormTextFieldSize, + HelpText, + HelpTextSeverity, } from '../../../component-library'; import { + BackgroundColor, BlockSize, + BorderRadius, Display, + FlexDirection, + JustifyContent, TextVariant, } from '../../../../helpers/constants/design-system'; import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { isWebUrl } from '../../../../../app/scripts/lib/util'; -const AddRpcUrlModal = () => { +const AddRpcUrlModal = ({ + onAdded, +}: { + onAdded: (url: string, name?: string) => void; +}) => { const t = useI18nContext(); + const [url, setUrl] = useState(); + const [error, setError] = useState(); + const nameRef = useRef(null); + + useEffect(() => { + if (url && !isWebUrl(url)) { + setError(isWebUrl(`https://${url}`) ? t('urlErrorMsg') : t('invalidRPC')); + } else { + setError(undefined); + } + }, [url]); + return ( - - + + + setUrl(e.target.value)} + /> + {error && ( + {error} + )} + + - ({})} > - {t('addUrl')} - + { + if (url && !error && nameRef.current) { + onAdded(url, nameRef.current.value || undefined); + } + }} + > + {t('addUrl')} + + ); }; diff --git a/ui/components/multichain/network-list-menu/add-rpc-url-modal/index.scss b/ui/components/multichain/network-list-menu/add-rpc-url-modal/index.scss new file mode 100644 index 000000000000..27d1fe4c20fd --- /dev/null +++ b/ui/components/multichain/network-list-menu/add-rpc-url-modal/index.scss @@ -0,0 +1,9 @@ +.add-rpc-modal { + overflow-y: auto; + + &__footer { + position: sticky; + bottom: 0; + box-shadow: 0 0 8px 0 var(--color-shadow-default); + } +}