From 763592113fadedae4a9ecfa87b8b84dc86a11ab9 Mon Sep 17 00:00:00 2001 From: Korbinian Date: Thu, 28 Sep 2023 05:53:32 +0200 Subject: [PATCH] feat(bridge-ui-v2): NFT bridge stepper (#14811) --- .../src/components/Bridge/Bridge.svelte | 85 ++++++++++++++----- .../src/components/Bridge/BridgeTabs.svelte | 25 ++++-- .../src/components/Bridge/state.ts | 3 + .../src/components/Bridge/types.ts | 12 +++ .../src/components/Card/Card.svelte | 4 +- .../src/components/Stepper/Step.svelte | 13 +++ .../src/components/Stepper/Stepper.svelte | 23 +++++ .../src/components/Stepper/index.ts | 2 + packages/bridge-ui-v2/src/i18n/en.json | 18 +++- packages/bridge-ui-v2/src/styles/override.css | 31 +++++++ 10 files changed, 185 insertions(+), 31 deletions(-) create mode 100644 packages/bridge-ui-v2/src/components/Bridge/types.ts create mode 100644 packages/bridge-ui-v2/src/components/Stepper/Step.svelte create mode 100644 packages/bridge-ui-v2/src/components/Stepper/Stepper.svelte create mode 100644 packages/bridge-ui-v2/src/components/Stepper/index.ts diff --git a/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte b/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte index a74cfea3f57..cd139d7f688 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte @@ -6,11 +6,13 @@ import { chainConfig } from '$chainConfig'; import { FlatAlert } from '$components/Alert'; import ChainSelectorWrapper from '$components/Bridge/ChainSelectorWrapper.svelte'; + import { Button } from '$components/Button'; import { Card } from '$components/Card'; import { successToast, warningToast } from '$components/NotificationToast'; import { errorToast, infoToast } from '$components/NotificationToast/NotificationToast.svelte'; import { OnAccount } from '$components/OnAccount'; import { OnNetwork } from '$components/OnNetwork'; + import { Step, Stepper } from '$components/Stepper'; import { TokenDropdown } from '$components/TokenDropdown'; import { type BridgeArgs, @@ -41,8 +43,18 @@ import Amount from './Amount.svelte'; import { ProcessingFee } from './ProcessingFee'; import Recipient from './Recipient.svelte'; - import { bridgeService, destNetwork, enteredAmount, processingFee, recipientAddress, selectedToken } from './state'; - + import { + activeBridge, + bridgeService, + destNetwork, + enteredAmount, + processingFee, + recipientAddress, + selectedToken, + } from './state'; + import { BridgeTypes, NFTSteps } from './types'; + + let activeStep: NFTSteps = NFTSteps.IMPORT; let amountComponent: Amount; let recipientComponent: Recipient; let processingFeeComponent: ProcessingFee; @@ -296,33 +308,68 @@ } } } + + const nextStep = () => (activeStep = Math.min(activeStep + 1, NFTSteps.CONFIRM)); + const back = () => (activeStep = Math.max(activeStep - 1, NFTSteps.IMPORT)); + + let nftStepTitle: string; + let nftStepDescription: string; + + $: { + const stepKey = NFTSteps[activeStep].toLowerCase(); // Convert enum to string and to lowercase + nftStepTitle = $t(`bridge.title.nft.${stepKey}`); + nftStepDescription = $t(`bridge.description.nft.${stepKey}`); + } + $: if ($selectedToken && amountComponent) { amountComponent.validateAmount(); } - -
-
- -
+{#if $activeBridge === BridgeTypes.FUNGIBLE} + +
+
+ +
- - {#if $selectedToken?.symbol === 'BLL' && !$selectedToken?.imported} - - {/if} - + + {#if $selectedToken?.symbol === 'BLL' && !$selectedToken?.imported} + + {/if} + -
- - -
+
+ + +
-
+
- + +
+ +{:else if $activeBridge === BridgeTypes.NFT} +
+ + {$t('bridge.title.nft.import')} + {$t('bridge.title.nft.review')} + {$t('bridge.title.nft.confirm')} + + + +
+ + +
+
- +{/if} diff --git a/packages/bridge-ui-v2/src/components/Bridge/BridgeTabs.svelte b/packages/bridge-ui-v2/src/components/Bridge/BridgeTabs.svelte index b5a4b7c1495..9a8115cc7bb 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/BridgeTabs.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/BridgeTabs.svelte @@ -1,25 +1,34 @@ {#if PUBLIC_NFT_BRIDGE_ENABLED === 'true'}
- + - +
{/if} diff --git a/packages/bridge-ui-v2/src/components/Bridge/state.ts b/packages/bridge-ui-v2/src/components/Bridge/state.ts index 3a9ea5360c7..7b9c406ee73 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/state.ts +++ b/packages/bridge-ui-v2/src/components/Bridge/state.ts @@ -5,6 +5,8 @@ import { bridges } from '$libs/bridge'; import { chains } from '$libs/chain'; import type { Token } from '$libs/token'; +import { type BridgeType, BridgeTypes } from './types'; + // Note: we could combine this with Context API, but since we'll only // have one Bridge component, it would be an overkill. If we wanted to // instantiate multiple Bridge components, then we'd need to use @@ -14,6 +16,7 @@ import type { Token } from '$libs/token'; // but once again, we don't need such level of security that we have to // prevent other components outside the Bridge from accessing this store. +export const activeBridge = writable(BridgeTypes.FUNGIBLE); export const selectedToken = writable>(null); export const tokenBalance = writable>(null); export const enteredAmount = writable(BigInt(0)); diff --git a/packages/bridge-ui-v2/src/components/Bridge/types.ts b/packages/bridge-ui-v2/src/components/Bridge/types.ts new file mode 100644 index 00000000000..ff01ce4e5b0 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/types.ts @@ -0,0 +1,12 @@ +export enum BridgeTypes { + FUNGIBLE = 'FUNGIBLE', + NFT = 'NFT', +} + +export enum NFTSteps { + IMPORT, + REVIEW, + CONFIRM, +} + +export type BridgeType = BridgeTypes; diff --git a/packages/bridge-ui-v2/src/components/Card/Card.svelte b/packages/bridge-ui-v2/src/components/Card/Card.svelte index cd63a76fc11..92db7775a1f 100644 --- a/packages/bridge-ui-v2/src/components/Card/Card.svelte +++ b/packages/bridge-ui-v2/src/components/Card/Card.svelte @@ -18,7 +18,9 @@
-

{title}

+ {#if title} +

{title}

+ {/if} {#if text}

{text}

{/if} diff --git a/packages/bridge-ui-v2/src/components/Stepper/Step.svelte b/packages/bridge-ui-v2/src/components/Stepper/Step.svelte new file mode 100644 index 00000000000..690dac2883c --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Stepper/Step.svelte @@ -0,0 +1,13 @@ + + +
  • + +
  • diff --git a/packages/bridge-ui-v2/src/components/Stepper/Stepper.svelte b/packages/bridge-ui-v2/src/components/Stepper/Stepper.svelte new file mode 100644 index 00000000000..913d5787982 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Stepper/Stepper.svelte @@ -0,0 +1,23 @@ + + +
    +
    +
      + +
    +
    +
    diff --git a/packages/bridge-ui-v2/src/components/Stepper/index.ts b/packages/bridge-ui-v2/src/components/Stepper/index.ts new file mode 100644 index 00000000000..5a781fc0521 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Stepper/index.ts @@ -0,0 +1,2 @@ +export { default as Step } from './Step.svelte'; +export { default as Stepper } from './Stepper.svelte'; diff --git a/packages/bridge-ui-v2/src/i18n/en.json b/packages/bridge-ui-v2/src/i18n/en.json index 642c98a7cfa..4933eed0168 100644 --- a/packages/bridge-ui-v2/src/i18n/en.json +++ b/packages/bridge-ui-v2/src/i18n/en.json @@ -12,9 +12,20 @@ "bridge": { "title": { "default": "Bridge Token", - "nft": "Bridge NFT" + "nft": { + "import": "Import NFT", + "review": "Review", + "confirm": "Confirm" + } + }, + "description": { + "default": "Send your assets across chains.", + "nft": { + "import": "Transfer your NFTs across chains", + "review": "Verify your NFT details.", + "confirm": "Confirm your NFT details." + } }, - "description": "Send your assets across chains.", "actions": { "approve": { "tx": "Transaction sent to approve {token} tokens. Click here to see it in the explorer.", @@ -48,7 +59,8 @@ "approved": "Approved", "bridge": "Bridge", "bridging": "Bridging", - "import": "Fetch NFT data" + "fetch": "Fetch NFT data", + "import": "Import" } }, "recipient": { diff --git a/packages/bridge-ui-v2/src/styles/override.css b/packages/bridge-ui-v2/src/styles/override.css index 664d4265d39..7237d3036e5 100644 --- a/packages/bridge-ui-v2/src/styles/override.css +++ b/packages/bridge-ui-v2/src/styles/override.css @@ -47,3 +47,34 @@ input[type='number'] { flex-direction: column; align-items: center; } + +.step:after { + height: 0px !important; + width: 0px !important; +} + +.step-primary:after { + height: 8px !important; + width: 8px !important; +} + +.step:before { + background-color: rgba(255, 198, 233, 0.2) !important; + height: 2px !important; +} + +.step-primary:before { + background-color: #e81899 !important; + height: 2px !important; +} + +.step-previous:before { + background-color: #e81899 !important; + height: 2px !important; +} + +.step-previous:after { + @apply step-primary; + height: 0px !important; + width: 0px !important; +}