From 6885c34518262b9a53d7df4c7d52f49c4baeb2f1 Mon Sep 17 00:00:00 2001
From: Pete Watters <2938440+pete-watters@users.noreply.github.com>
Date: Tue, 5 Dec 2023 12:10:58 +0000
Subject: [PATCH] chore: replace drawer with dialog, add containers and global
header footers, refactor onboarding, ref #4371
---
.storybook/main.ts | 6 +
.storybook/preview.ts | 7 +
.storybook/viewports.ts | 49 ++++
package.json | 1 +
public/html/popup-center.html | 12 -
src/app/app.tsx | 28 +--
src/app/common/hooks/use-drawers.ts | 26 ---
src/app/common/hooks/use-event-listener.ts | 74 ------
src/app/common/hooks/use-latest-ref.ts | 17 --
src/app/common/hooks/use-media-query.ts | 23 --
src/app/common/hooks/use-route-header.ts | 16 --
src/app/common/utils.ts | 4 -
src/app/common/utils/copy-to-clipboard.ts | 6 +
src/app/common/utils/use-interval.ts | 26 ---
src/app/common/utils/use-waiting-message.ts | 39 ----
.../components/account/account-addresses.tsx | 5 +-
src/app/components/app-version.tsx | 27 ++-
.../bitcoin-custom-fee/bitcoin-custom-fee.tsx | 12 +-
.../broadcast-error-dialog.tsx} | 22 +-
.../broadcast-error-drawer.tsx | 17 --
.../components/centered-page-container.tsx | 15 --
.../choose-asset-container.tsx | 4 +-
.../crypto-asset-list.layout.tsx | 10 -
.../choose-crypto-asset/crypto-asset-list.tsx | 8 +-
src/app/components/drawer/base-drawer.tsx | 127 -----------
.../drawer/components/drawer-header.tsx | 56 -----
.../components/drawer/controlled-drawer.tsx | 30 ---
.../generic-error/generic-error.tsx | 5 -
src/app/components/header.tsx | 86 -------
src/app/components/leather-logo.tsx | 23 --
src/app/components/modal-header.tsx | 86 -------
src/app/components/network-mode-badge.tsx | 33 ---
src/app/components/preview-button.tsx | 24 --
src/app/components/request-password.tsx | 128 +++++------
.../components/secret-key/secret-key-grid.tsx | 24 --
.../secret-key/two-column.layout.tsx | 56 -----
src/app/components/status-ready.tsx | 2 +-
.../activity-list/components/tab-wrapper.tsx | 3 +-
src/app/features/add-network/add-network.tsx | 15 +-
src/app/features/asset-list/asset-list.tsx | 2 +-
.../bitcoin-choose-fee/bitcoin-choose-fee.tsx | 4 +-
.../features/collectibles/collectibles.tsx | 2 +-
.../_collectible-types/collectible-other.tsx | 2 +-
.../collectible-text.layout.tsx | 2 +-
...ibes.layout.tsx => collectible.layout.tsx} | 16 +-
.../features/container/container.layout.tsx | 18 --
src/app/features/container/container.tsx | 153 +++++++++++--
src/app/features/container/total-balance.tsx | 57 +++++
.../container/utils/get-popup-header.ts | 38 ++++
.../container/utils/get-title-from-url.ts | 35 +++
.../features/container/utils/route-helpers.ts | 49 ++++
.../current-account-avatar.tsx | 13 +-
.../features/current-account/popup-header.tsx | 69 ------
.../components/edit-nonce-field.tsx | 0
.../components/edit-nonce-form.tsx | 0
.../edit-nonce-dialog/edit-nonce-dialog.tsx} | 28 +--
.../high-fee-dialog/high-fee-dialog.tsx | 74 ++++++
.../components/fee-multiplier-button.tsx | 0
.../components/fee-multiplier.tsx | 0
.../components/increase-btc-fee-form.tsx | 0
.../components/increase-fee-actions.tsx | 0
.../components/increase-fee-field.tsx | 2 +-
.../components/increase-stx-fee-form.tsx | 0
.../hooks/use-btc-increase-fee.ts | 0
.../hooks/use-selected-tx.ts | 0
.../increase-btc-fee-dialog.tsx} | 14 +-
.../increase-fee-dialog.tsx} | 15 +-
.../increase-fee-sent-dialog.tsx} | 13 +-
.../increase-stx-fee-dialog.tsx} | 6 +-
.../leather-intro-dialog/confetti-config.ts | 0
.../leather-intro-dialog.tsx | 5 -
.../leather-intro-steps.tsx | 0
.../components/account-list-unavailable.tsx | 0
.../components/switch-account-list-item.tsx | 3 +-
.../components/switch-account-list.tsx | 13 +-
.../switch-account-dialog.tsx | 62 +++++
.../features/errors/app-error-boundary.tsx | 4 -
.../components/high-fee-confirmation.tsx | 48 ----
.../high-fee-drawer/high-fee-drawer.tsx | 28 ---
.../hiro-messages/in-app-messages.tsx | 1 +
src/app/features/html-head/head-provider.tsx | 14 +-
.../ledger/components/ledger-wrapper.tsx | 2 +-
.../jwt-signing/ledger-sign-jwt-container.tsx | 16 +-
.../ledger-stacks-sign-msg-container.tsx | 21 +-
.../request-keys/request-keys-flow.tsx | 11 +-
.../tx-signing/tx-signing-flow.tsx | 21 +-
.../connect-ledger-error.layout.tsx | 2 +-
.../connect-device/connect-ledger-start.tsx | 6 +-
.../unsupported-browser.layout.tsx | 19 +-
.../features/message-signer/hash-drawer.tsx | 3 +-
.../message-signer/message-preview-box.tsx | 7 +-
.../features/psbt-signer/components/index.ts | 9 +
.../components/psbt-request-actions.tsx | 30 +--
.../components/psbt-signer.layout.tsx | 19 --
src/app/features/psbt-signer/psbt-signer.tsx | 42 ++--
...trieve-taproot-to-native-segwit.layout.tsx | 6 +-
.../secret-key-displayer.tsx | 8 +-
.../components/settings-menu-item.tsx | 27 ---
.../components/settings-menu-wrapper.tsx | 27 ---
.../settings-dropdown/settings-dropdown.tsx | 170 --------------
.../components/advanced-menu-items.tsx | 27 +--
.../components/ledger-item-row.tsx | 0
.../components/network-list-item.layout.tsx | 8 +-
.../settings/network}/network-list-item.tsx | 0
src/app/features/settings/network/network.tsx | 78 +++++++
src/app/features/settings/settings.tsx | 214 ++++++++++++++++++
.../settings/sign-out/sign-out-confirm.tsx | 36 +++
.../features/settings/sign-out/sign-out.tsx | 105 +++++++++
.../theme/theme-dialog.tsx} | 14 +-
.../theme/theme-list-item.tsx} | 22 +-
.../components/nested-tuple-displayer.tsx | 2 +-
.../stacks-message-signing.tsx | 3 -
.../hooks/use-stacks-transaction-summary.ts | 1 -
.../stacks-transaction-signer.tsx | 17 +-
.../submit-action.tsx | 10 +-
.../transaction-error/error-messages.tsx | 12 +-
.../components/create-account-action.tsx | 25 --
.../switch-account-drawer.tsx | 55 -----
.../features/theme-drawer/theme-drawer.tsx | 18 --
.../features/theme-drawer/theme-list-item.tsx | 25 --
.../bitcoin-contract-list.tsx | 7 +-
.../bitcoin-contract-list-item-layout.tsx | 2 +-
.../bitcoin-contract-list-layout.tsx | 22 --
.../bitcoin-contract-request.tsx | 8 +-
.../bitcoin-contract-request-actions.tsx | 51 ++---
.../bitcoin-contract-request-layout.tsx | 20 --
.../pages/choose-account/choose-account.tsx | 2 -
.../choose-account/components/accounts.tsx | 2 +-
.../choose-asset-to-fund.tsx | 4 -
.../fund/components/fund-account-tile.tsx | 2 +-
src/app/pages/fund/components/fund.layout.tsx | 56 ++---
src/app/pages/fund/fiat-providers-list.tsx | 20 +-
src/app/pages/fund/fund.tsx | 8 +-
.../pages/home/components/account-actions.tsx | 8 +-
.../pages/home/components/account-area.tsx | 28 ---
.../home/components/account-info-card.tsx | 67 ------
src/app/pages/home/components/home-tabs.tsx | 8 +-
src/app/pages/home/components/home.layout.tsx | 31 ---
src/app/pages/home/components/send-button.tsx | 7 +-
src/app/pages/home/home.tsx | 45 ++--
.../allow-diagnostics-layout.tsx | 84 +++----
.../allow-diagnostics/allow-diagnostics.tsx | 4 -
.../back-up-secret-key/back-up-secret-key.tsx | 48 +++-
.../components/back-up-secret-key.content.tsx | 41 ----
.../set-password/components/password-bars.tsx | 28 ++-
.../onboarding/set-password/set-password.tsx | 64 ++----
.../sign-in/components/sign-in.content.tsx | 26 ---
.../onboarding/sign-in/mnemonic-form.tsx | 47 ++--
src/app/pages/onboarding/sign-in/sign-in.tsx | 53 ++---
.../onboarding/welcome/welcome.layout.tsx | 128 -----------
src/app/pages/onboarding/welcome/welcome.tsx | 7 +-
.../components/receive-collectibles.tsx | 55 +++++
.../receive/components/receive-items.tsx | 21 --
.../components/receive-tokens.layout.tsx | 28 ++-
.../receive/components/receive-tokens.tsx | 44 ++++
src/app/pages/receive/receive-btc.tsx | 16 +-
src/app/pages/receive/receive-dialog.tsx | 126 +++++++++++
src/app/pages/receive/receive-modal.tsx | 151 ------------
src/app/pages/receive/receive-ordinal.tsx | 14 +-
src/app/pages/receive/receive-stx.tsx | 16 +-
.../rpc-send-transfer-confirmation.tsx | 1 -
.../rpc-send-transfer-container.tsx | 5 -
.../rpc-sign-bip322-message.tsx | 4 -
.../pages/rpc-sign-psbt/use-rpc-sign-psbt.tsx | 1 -
.../components/add-network-button.tsx | 17 --
.../components/network-list.layout.tsx | 9 -
.../components/network-status-indicator.tsx | 10 -
.../pages/select-network/select-network.tsx | 67 ------
.../choose-crypto-asset.tsx | 18 +-
.../locked-bitcoin-summary.tsx | 4 -
.../send-inscription-choose-fee.tsx | 12 +-
.../send-inscription-form.tsx | 12 +-
.../send-inscription-review.tsx | 12 +-
.../sent-inscription-summary.tsx | 11 +-
src/app/pages/send/send-container.tsx | 30 ---
.../components/form-footer.tsx | 30 ---
.../account-list-item.tsx | 2 +-
.../recipient-accounts-dialog.tsx} | 31 +--
.../select-account-button.tsx | 0
.../recipient-type-dropdown.tsx | 2 +-
.../send-crypto-asset-form.layout.tsx | 26 +--
.../form/brc-20/brc-20-choose-fee.tsx | 9 -
.../brc-20/brc20-send-form-confirmation.tsx | 5 -
.../form/brc-20/brc20-send-form.tsx | 85 ++++---
.../form/btc/btc-choose-fee.tsx | 6 +-
.../form/btc/btc-send-form-confirmation.tsx | 5 -
.../form/btc/btc-send-form.tsx | 98 ++++----
.../form/btc/use-btc-choose-fee.tsx | 10 -
.../form/stacks/stacks-common-send-form.tsx | 71 ++++--
.../stacks/stacks-send-form-confirmation.tsx | 14 +-
.../stacks/use-stacks-common-send-form.tsx | 13 +-
.../form/stx/stx-send-form.tsx | 4 +
.../form/stx/use-stx-send-form.tsx | 6 +-
.../hooks/use-send-form-navigate.ts | 4 -
.../send-crypto-asset-form.routes.tsx | 52 +++--
.../send/sent-summary/brc20-sent-summary.tsx | 4 -
.../send/sent-summary/btc-sent-summary.tsx | 4 -
.../send/sent-summary/stx-sent-summary.tsx | 4 -
.../sign-out-confirm.layout.tsx | 115 ----------
.../sign-out-confirm/sign-out-confirm.tsx | 27 ---
src/app/pages/swap/alex-swap-container.tsx | 6 +-
.../swap/components/swap-container.layout.tsx | 25 --
.../components/swap-asset-list.layout.tsx | 9 -
.../components/swap-asset-list.tsx | 7 +-
.../swap-choose-asset/swap-choose-asset.tsx | 29 +--
.../pages/swap/swap-review/swap-review.tsx | 4 -
src/app/pages/swap/swap.tsx | 4 -
.../transaction-request.tsx | 20 +-
src/app/pages/unlock.tsx | 41 +---
.../update-profile-request.tsx | 4 -
.../components/view-secret-key.content.tsx | 24 --
.../pages/view-secret-key/view-secret-key.tsx | 46 ++--
src/app/routes/app-routes.tsx | 28 +--
src/app/routes/receive-routes.tsx | 6 +-
src/app/routes/request-routes.tsx | 8 +-
src/app/routes/settings-routes.tsx | 15 --
src/app/store/networks/networks.ts | 2 +
src/app/store/settings/settings.selectors.ts | 20 +-
src/app/store/settings/settings.slice.ts | 9 -
src/app/store/ui/ui.hooks.ts | 30 +--
src/app/store/ui/ui.ts | 11 -
.../account-avatar}/account-avatar-item.tsx | 2 +-
.../account-avatar}/account-avatar.tsx | 0
.../account/account.card.stories.tsx | 33 +++
.../ui/components/account/account.card.tsx | 66 ++++++
.../components/account}/action-button.tsx | 14 +-
.../avatar-icon}/accessible-icon.tsx | 0
.../bullet-separator/bullet-separator.tsx | 2 +-
.../ui/components/button/button.stories.tsx | 29 +--
src/app/ui/components/button/button.tsx | 5 +-
.../containers/container.layout.tsx | 30 +++
.../containers/dialog/dialog.stories.tsx | 15 ++
.../components/containers/dialog/dialog.tsx | 61 +++++
.../containers/footers}/available-balance.tsx | 18 +-
.../containers/footers/footer.stories.tsx | 153 +++++++++++++
.../components/containers/footers/footer.tsx | 32 +++
.../headers/components/network-mode-badge.tsx | 27 +++
.../headers}/header-action-button.tsx | 26 ++-
.../containers/headers/header.stories.tsx | 22 ++
.../components/containers/headers/header.tsx | 86 +++++++
.../containers/popup/popup-card.tsx | 21 ++
.../dropdown-menu-item.layout.tsx | 0
.../dropdown-menu.stories.tsx | 0
.../dropdown-menu.tsx | 38 +++-
src/app/ui/components/flag/flag.stories.tsx | 4 +-
src/app/ui/components/item/item.stories.tsx | 10 +-
src/app/ui/components/link/link.stories.tsx | 14 --
src/app/ui/components/link/link.tsx | 2 +-
src/app/ui/components/logo.tsx | 20 ++
.../mnemonic-key/mnemonic-word-input.tsx | 0
.../mnemonic-key/utils/error-handling.ts | 0
.../mnemonic-key/utils/validation.ts | 0
.../components/secret-key/secret-key-grid.tsx | 20 ++
.../secret-key}/secret-key-word.tsx | 2 +-
.../secret-key/secret-key.layout.tsx} | 47 ++--
src/app/ui/icons/docs/icons.mdx | 4 +-
src/app/ui/layout/card/card-content.tsx | 22 ++
src/app/ui/layout/card/card.stories.tsx | 30 +++
src/app/ui/layout/card/card.tsx | 26 +++
.../ui/layout/page/page.layout.stories.tsx | 21 ++
src/app/ui/layout/page/page.layout.tsx | 24 ++
src/app/ui/pages/home.layout.stories.tsx | 51 +++++
src/app/ui/pages/home.layout.tsx | 31 +++
.../ui/pages/two-column.layout.stories.tsx | 20 ++
src/app/ui/pages/two-column.layout.tsx | 60 +++++
src/app/ui/pages/welcome.layout.tsx | 143 ++++++++++++
src/app/ui/utils/prism.tsx | 2 +-
src/background/messaging/messaging-utils.ts | 4 +-
src/background/popup-center.ts | 41 ----
src/background/popup.ts | 63 ++++++
src/shared/constants.ts | 3 -
src/shared/route-urls.ts | 5 +-
src/shared/utils/px-string-to-number.spec.ts | 12 +
src/shared/utils/px-string-to-number.ts | 3 +
test-app/src/components/app.tsx | 19 +-
test-app/src/components/bns.tsx | 2 +
test-app/src/components/counter-actions.tsx | 30 +--
test-app/src/components/header.tsx | 32 ---
tests/page-object-models/home.page.ts | 20 +-
tests/page-object-models/onboarding.page.ts | 1 -
tests/page-object-models/send.page.ts | 2 +-
tests/selectors/home.selectors.ts | 4 +-
tests/selectors/onboarding.selectors.ts | 2 +-
tests/selectors/settings.selectors.ts | 3 +-
tests/selectors/shared-component.selectors.ts | 4 +-
...settings-menu.spec.ts => settings.spec.ts} | 1 +
theme/global/full-page-styles.ts | 14 --
theme/global/global.ts | 61 ++++-
theme/global/popup-center-styles.ts | 8 -
theme/global/popup-styles.ts | 24 --
theme/tokens.ts | 29 +++
webpack/webpack.config.base.js | 5 -
292 files changed, 3535 insertions(+), 3737 deletions(-)
create mode 100644 .storybook/viewports.ts
delete mode 100644 public/html/popup-center.html
delete mode 100644 src/app/common/hooks/use-drawers.ts
delete mode 100644 src/app/common/hooks/use-event-listener.ts
delete mode 100644 src/app/common/hooks/use-latest-ref.ts
delete mode 100644 src/app/common/hooks/use-media-query.ts
delete mode 100644 src/app/common/hooks/use-route-header.ts
create mode 100644 src/app/common/utils/copy-to-clipboard.ts
delete mode 100644 src/app/common/utils/use-interval.ts
delete mode 100644 src/app/common/utils/use-waiting-message.ts
rename src/app/components/{broadcast-error-drawer/broadcast-error-drawer.layout.tsx => broadcast-error-dialog/broadcast-error-dialog.tsx} (62%)
delete mode 100644 src/app/components/broadcast-error-drawer/broadcast-error-drawer.tsx
delete mode 100644 src/app/components/centered-page-container.tsx
delete mode 100644 src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
delete mode 100644 src/app/components/drawer/base-drawer.tsx
delete mode 100644 src/app/components/drawer/components/drawer-header.tsx
delete mode 100644 src/app/components/drawer/controlled-drawer.tsx
delete mode 100644 src/app/components/header.tsx
delete mode 100644 src/app/components/leather-logo.tsx
delete mode 100644 src/app/components/modal-header.tsx
delete mode 100644 src/app/components/network-mode-badge.tsx
delete mode 100644 src/app/components/preview-button.tsx
delete mode 100644 src/app/components/secret-key/secret-key-grid.tsx
delete mode 100644 src/app/components/secret-key/two-column.layout.tsx
rename src/app/features/collectibles/components/{collectibes.layout.tsx => collectible.layout.tsx} (79%)
delete mode 100644 src/app/features/container/container.layout.tsx
create mode 100644 src/app/features/container/total-balance.tsx
create mode 100644 src/app/features/container/utils/get-popup-header.ts
create mode 100644 src/app/features/container/utils/get-title-from-url.ts
create mode 100644 src/app/features/container/utils/route-helpers.ts
delete mode 100644 src/app/features/current-account/popup-header.tsx
rename src/app/features/{edit-nonce-drawer => dialogs/edit-nonce-dialog}/components/edit-nonce-field.tsx (100%)
rename src/app/features/{edit-nonce-drawer => dialogs/edit-nonce-dialog}/components/edit-nonce-form.tsx (100%)
rename src/app/features/{edit-nonce-drawer/edit-nonce-drawer.tsx => dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx} (76%)
create mode 100644 src/app/features/dialogs/high-fee-dialog/high-fee-dialog.tsx
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/fee-multiplier-button.tsx (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/fee-multiplier.tsx (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/increase-btc-fee-form.tsx (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/increase-fee-actions.tsx (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/increase-fee-field.tsx (98%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/components/increase-stx-fee-form.tsx (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/hooks/use-btc-increase-fee.ts (100%)
rename src/app/features/{increase-fee-drawer => dialogs/increase-fee-dialog}/hooks/use-selected-tx.ts (100%)
rename src/app/features/{increase-fee-drawer/increase-btc-fee-drawer.tsx => dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx} (69%)
rename src/app/features/{increase-fee-drawer/increase-fee-drawer.tsx => dialogs/increase-fee-dialog/increase-fee-dialog.tsx} (67%)
rename src/app/features/{increase-fee-drawer/increase-fee-sent-drawer.tsx => dialogs/increase-fee-dialog/increase-fee-sent-dialog.tsx} (60%)
rename src/app/features/{increase-fee-drawer/increase-stx-fee-drawer.tsx => dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx} (90%)
rename src/app/features/{ => dialogs}/leather-intro-dialog/confetti-config.ts (100%)
rename src/app/features/{ => dialogs}/leather-intro-dialog/leather-intro-dialog.tsx (90%)
rename src/app/features/{ => dialogs}/leather-intro-dialog/leather-intro-steps.tsx (100%)
rename src/app/features/{switch-account-drawer => dialogs/switch-account-dialog}/components/account-list-unavailable.tsx (100%)
rename src/app/features/{switch-account-drawer => dialogs/switch-account-dialog}/components/switch-account-list-item.tsx (95%)
rename src/app/features/{switch-account-drawer => dialogs/switch-account-dialog}/components/switch-account-list.tsx (79%)
create mode 100644 src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx
delete mode 100644 src/app/features/high-fee-drawer/components/high-fee-confirmation.tsx
delete mode 100644 src/app/features/high-fee-drawer/high-fee-drawer.tsx
create mode 100644 src/app/features/psbt-signer/components/index.ts
delete mode 100644 src/app/features/psbt-signer/components/psbt-signer.layout.tsx
delete mode 100644 src/app/features/settings-dropdown/components/settings-menu-item.tsx
delete mode 100644 src/app/features/settings-dropdown/components/settings-menu-wrapper.tsx
delete mode 100644 src/app/features/settings-dropdown/settings-dropdown.tsx
rename src/app/features/{settings-dropdown => settings}/components/advanced-menu-items.tsx (77%)
rename src/app/features/{settings-dropdown => settings}/components/ledger-item-row.tsx (100%)
rename src/app/{pages/select-network => features/settings/network}/components/network-list-item.layout.tsx (88%)
rename src/app/{pages/select-network => features/settings/network}/network-list-item.tsx (100%)
create mode 100644 src/app/features/settings/network/network.tsx
create mode 100644 src/app/features/settings/settings.tsx
create mode 100644 src/app/features/settings/sign-out/sign-out-confirm.tsx
create mode 100644 src/app/features/settings/sign-out/sign-out.tsx
rename src/app/features/{theme-drawer/theme-list.tsx => settings/theme/theme-dialog.tsx} (71%)
rename src/app/features/{theme-drawer/theme-list-item-layout.tsx => settings/theme/theme-list-item.tsx} (54%)
delete mode 100644 src/app/features/switch-account-drawer/components/create-account-action.tsx
delete mode 100644 src/app/features/switch-account-drawer/switch-account-drawer.tsx
delete mode 100644 src/app/features/theme-drawer/theme-drawer.tsx
delete mode 100644 src/app/features/theme-drawer/theme-list-item.tsx
delete mode 100644 src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-layout.tsx
delete mode 100644 src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-layout.tsx
delete mode 100644 src/app/pages/home/components/account-area.tsx
delete mode 100644 src/app/pages/home/components/account-info-card.tsx
delete mode 100644 src/app/pages/home/components/home.layout.tsx
delete mode 100644 src/app/pages/onboarding/back-up-secret-key/components/back-up-secret-key.content.tsx
delete mode 100644 src/app/pages/onboarding/sign-in/components/sign-in.content.tsx
delete mode 100644 src/app/pages/onboarding/welcome/welcome.layout.tsx
create mode 100644 src/app/pages/receive/components/receive-collectibles.tsx
delete mode 100644 src/app/pages/receive/components/receive-items.tsx
create mode 100644 src/app/pages/receive/components/receive-tokens.tsx
create mode 100644 src/app/pages/receive/receive-dialog.tsx
delete mode 100644 src/app/pages/receive/receive-modal.tsx
delete mode 100644 src/app/pages/select-network/components/add-network-button.tsx
delete mode 100644 src/app/pages/select-network/components/network-list.layout.tsx
delete mode 100644 src/app/pages/select-network/components/network-status-indicator.tsx
delete mode 100644 src/app/pages/select-network/select-network.tsx
delete mode 100644 src/app/pages/send/send-container.tsx
delete mode 100644 src/app/pages/send/send-crypto-asset-form/components/form-footer.tsx
rename src/app/pages/send/send-crypto-asset-form/components/{recipient-accounts-drawer => recipient-accounts-dialog}/account-list-item.tsx (95%)
rename src/app/pages/send/send-crypto-asset-form/components/{recipient-accounts-drawer/recipient-accounts-drawer.tsx => recipient-accounts-dialog/recipient-accounts-dialog.tsx} (60%)
rename src/app/pages/send/send-crypto-asset-form/components/{recipient-accounts-drawer => recipient-accounts-dialog}/select-account-button.tsx (100%)
delete mode 100644 src/app/pages/sign-out-confirm/sign-out-confirm.layout.tsx
delete mode 100644 src/app/pages/sign-out-confirm/sign-out-confirm.tsx
delete mode 100644 src/app/pages/swap/components/swap-container.layout.tsx
delete mode 100644 src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
delete mode 100644 src/app/pages/view-secret-key/components/view-secret-key.content.tsx
delete mode 100644 src/app/routes/settings-routes.tsx
rename src/app/{components/account => ui/components/account/account-avatar}/account-avatar-item.tsx (76%)
rename src/app/{components/account => ui/components/account/account-avatar}/account-avatar.tsx (100%)
create mode 100644 src/app/ui/components/account/account.card.stories.tsx
create mode 100644 src/app/ui/components/account/account.card.tsx
rename src/app/{pages/home/components => ui/components/account}/action-button.tsx (63%)
rename src/app/{pages/home/components => ui/components/avatar-icon}/accessible-icon.tsx (100%)
create mode 100644 src/app/ui/components/containers/container.layout.tsx
create mode 100644 src/app/ui/components/containers/dialog/dialog.stories.tsx
create mode 100644 src/app/ui/components/containers/dialog/dialog.tsx
rename src/app/{components => ui/components/containers/footers}/available-balance.tsx (62%)
create mode 100644 src/app/ui/components/containers/footers/footer.stories.tsx
create mode 100644 src/app/ui/components/containers/footers/footer.tsx
create mode 100644 src/app/ui/components/containers/headers/components/network-mode-badge.tsx
rename src/app/{components/drawer/components => ui/components/containers/headers}/header-action-button.tsx (62%)
create mode 100644 src/app/ui/components/containers/headers/header.stories.tsx
create mode 100644 src/app/ui/components/containers/headers/header.tsx
create mode 100644 src/app/ui/components/containers/popup/popup-card.tsx
rename src/app/ui/components/{dowpdown-menu => dropdown-menu}/dropdown-menu-item.layout.tsx (100%)
rename src/app/ui/components/{dowpdown-menu => dropdown-menu}/dropdown-menu.stories.tsx (100%)
rename src/app/ui/components/{dowpdown-menu => dropdown-menu}/dropdown-menu.tsx (73%)
create mode 100644 src/app/ui/components/logo.tsx
rename src/app/{ => ui}/components/secret-key/mnemonic-key/mnemonic-word-input.tsx (100%)
rename src/app/{ => ui}/components/secret-key/mnemonic-key/utils/error-handling.ts (100%)
rename src/app/{ => ui}/components/secret-key/mnemonic-key/utils/validation.ts (100%)
create mode 100644 src/app/ui/components/secret-key/secret-key-grid.tsx
rename src/app/{features/secret-key-displayer/components => ui/components/secret-key}/secret-key-word.tsx (93%)
rename src/app/{features/secret-key-displayer/secret-key-displayer.layout.tsx => ui/components/secret-key/secret-key.layout.tsx} (63%)
create mode 100644 src/app/ui/layout/card/card-content.tsx
create mode 100644 src/app/ui/layout/card/card.stories.tsx
create mode 100644 src/app/ui/layout/card/card.tsx
create mode 100644 src/app/ui/layout/page/page.layout.stories.tsx
create mode 100644 src/app/ui/layout/page/page.layout.tsx
create mode 100644 src/app/ui/pages/home.layout.stories.tsx
create mode 100644 src/app/ui/pages/home.layout.tsx
create mode 100644 src/app/ui/pages/two-column.layout.stories.tsx
create mode 100644 src/app/ui/pages/two-column.layout.tsx
create mode 100644 src/app/ui/pages/welcome.layout.tsx
delete mode 100644 src/background/popup-center.ts
create mode 100644 src/background/popup.ts
create mode 100644 src/shared/utils/px-string-to-number.spec.ts
create mode 100644 src/shared/utils/px-string-to-number.ts
delete mode 100644 test-app/src/components/header.tsx
rename tests/specs/settings/{settings-menu.spec.ts => settings.spec.ts} (97%)
delete mode 100644 theme/global/full-page-styles.ts
delete mode 100644 theme/global/popup-center-styles.ts
delete mode 100644 theme/global/popup-styles.ts
diff --git a/.storybook/main.ts b/.storybook/main.ts
index 983884a4ff8..79a6524c05e 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -34,6 +34,12 @@ const config: StorybookConfig = {
},
],
},
+
+ {
+ test: /\.(ts|tsx)$/,
+ loader: 'esbuild-loader',
+ options: { tsconfig: './tsconfig.json', target: 'es2020' },
+ },
],
},
},
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index ae4ce4cab9a..fe3b4426509 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -1,6 +1,7 @@
import type { Preview } from '@storybook/react';
import '../src/app/index.css';
+import { customViewports } from './viewports';
const preview: Preview = {
parameters: {
@@ -24,6 +25,12 @@ const preview: Preview = {
date: /Date$/i,
},
},
+ viewport: {
+ viewports: {
+ ...customViewports,
+ },
+ },
+ toc: true,
},
};
diff --git a/.storybook/viewports.ts b/.storybook/viewports.ts
new file mode 100644
index 00000000000..ddfe099aad4
--- /dev/null
+++ b/.storybook/viewports.ts
@@ -0,0 +1,49 @@
+import { breakpoints } from '@leather-wallet/tokens';
+
+// TODO import from '@leather-wallet/tokens'
+import { tokens } from '../theme/tokens';
+
+export const customViewports = {
+ popup: {
+ name: 'Popup',
+ styles: {
+ width: tokens.sizes.popupWidth.value,
+ height: tokens.sizes.popupHeight.value,
+ },
+ },
+ sm: {
+ name: 'sm',
+ styles: {
+ width: breakpoints.sm,
+ height: '100%',
+ },
+ },
+ md: {
+ name: 'md',
+ styles: {
+ width: breakpoints.md,
+ height: '100%',
+ },
+ },
+ lg: {
+ name: 'lg',
+ styles: {
+ width: breakpoints.lg,
+ height: '100%',
+ },
+ },
+ xl: {
+ name: 'xl',
+ styles: {
+ width: breakpoints.xl,
+ height: '100%',
+ },
+ },
+ '2xl': {
+ name: '2xl',
+ styles: {
+ width: breakpoints['2xl'],
+ height: '100%',
+ },
+ },
+};
diff --git a/package.json b/package.json
index 97cf8396508..8e08d8bf049 100644
--- a/package.json
+++ b/package.json
@@ -145,6 +145,7 @@
"@radix-ui/react-tabs": "1.0.4",
"@radix-ui/react-tooltip": "1.0.7",
"@radix-ui/themes": "2.0.3",
+ "@radix-ui/react-dialog": "1.0.5",
"@reduxjs/toolkit": "1.9.6",
"@scure/base": "1.1.3",
"@scure/bip32": "1.3.2",
diff --git a/public/html/popup-center.html b/public/html/popup-center.html
deleted file mode 100644
index 7d23e5be4ba..00000000000
--- a/public/html/popup-center.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/app.tsx b/src/app/app.tsx
index ac9526927ad..6cebc420b81 100644
--- a/src/app/app.tsx
+++ b/src/app/app.tsx
@@ -1,9 +1,8 @@
import { Suspense } from 'react';
+import { Toaster } from 'react-hot-toast';
import { Provider as ReduxProvider } from 'react-redux';
-import { radixBaseCSS } from '@radix-ui/themes/styles.css';
import { QueryClientProvider } from '@tanstack/react-query';
-import { styled } from 'leather-styles/jsx';
import { PersistGate } from 'redux-persist/integration/react';
import { queryClient } from '@app/common/persistence';
@@ -24,19 +23,22 @@ export function App() {
} persistor={persistor}>
- {/* TODO: this works but investigate importing radixBaseCSS in panda layer config */}
-
-
- }>
-
-
-
- {reactQueryDevToolsEnabled && }
-
-
-
+
+ }>
+
+
+
+ {reactQueryDevToolsEnabled && }
+
+
+
);
diff --git a/src/app/common/hooks/use-drawers.ts b/src/app/common/hooks/use-drawers.ts
deleted file mode 100644
index d92f2f48f9b..00000000000
--- a/src/app/common/hooks/use-drawers.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import {
- useShowHighFeeConfirmationState,
- useShowSettingsStore,
- useShowSwitchAccountsState,
- useShowTxSettingsCallback,
-} from '@app/store/ui/ui.hooks';
-
-export function useDrawers() {
- const [isShowingAccounts, setIsShowingSwitchAccountsState] = useShowSwitchAccountsState();
- const [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation] =
- useShowHighFeeConfirmationState();
-
- const [isShowingSettings, setIsShowingSettings] = useShowSettingsStore();
- const [isShowingTxSettingsCallback, setIsShowingTxSettingsCallback] = useShowTxSettingsCallback();
-
- return {
- isShowingAccounts,
- setIsShowingSwitchAccountsState,
- isShowingHighFeeConfirmation,
- setIsShowingHighFeeConfirmation,
- isShowingSettings,
- setIsShowingSettings,
- isShowingTxSettingsCallback,
- setIsShowingTxSettingsCallback,
- };
-}
diff --git a/src/app/common/hooks/use-event-listener.ts b/src/app/common/hooks/use-event-listener.ts
deleted file mode 100644
index b50275a17c4..00000000000
--- a/src/app/common/hooks/use-event-listener.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { useEffect } from 'react';
-
-import { useLatestRef } from './use-latest-ref';
-
-// eslint-disable-next-line @typescript-eslint/ban-types
-type FunctionArguments = T extends (...args: infer R) => any ? R : never;
-type AddEventListener = FunctionArguments;
-
-let _window: Window | undefined = undefined;
-
-// Note: Accessing "window" in IE11 is somewhat expensive, and calling "typeof window"
-// hits a memory leak, whereas aliasing it and calling "typeof _window" does not.
-// Caching the window value at the file scope lets us minimize the impact.
-try {
- _window = window;
-} catch (e) {
- /* no-op */
-}
-
-/**
- * Helper to get the window object. The helper will make sure to use a cached variable
- * of "window", to avoid overhead and memory leaks in IE11.
- */
-function getWindow(node?: HTMLElement | null): Window | undefined {
- return node?.ownerDocument?.defaultView ?? _window;
-}
-
-/**
- * Check if we can use the DOM. Useful for SSR purposes
- */
-function checkIsBrowser() {
- const _window = getWindow();
- return Boolean(
- // eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
- typeof _window !== 'undefined' && _window.document && _window.document.createElement
- );
-}
-
-const isBrowser = checkIsBrowser();
-
-/**
- * React hook to manage browser event listeners
- *
- * @param event the event name
- * @param handler the event handler function to execute
- * @param element the dom environment to execute against (defaults to `document`)
- * @param options the event listener options
- */
-export function useEventListener(
- event: keyof WindowEventMap,
- handler: (event: any) => void,
- element: Document | null = isBrowser ? document : null,
- options?: AddEventListener[2]
-) {
- const savedHandler = useLatestRef(handler);
-
- useEffect(() => {
- if (!element) return;
-
- const listener = (event: any) => {
- savedHandler.current(event);
- };
-
- element.addEventListener(event, listener, options);
-
- return () => {
- element.removeEventListener(event, listener, options);
- };
- }, [event, element, options, savedHandler]);
-
- return () => {
- element?.removeEventListener(event, savedHandler.current, options);
- };
-}
diff --git a/src/app/common/hooks/use-latest-ref.ts b/src/app/common/hooks/use-latest-ref.ts
deleted file mode 100644
index aa73b9c1b29..00000000000
--- a/src/app/common/hooks/use-latest-ref.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useEffect, useRef } from 'react';
-
-/**
- * React hook to persist any value between renders,
- * but keeps it up-to-date if it changes.
- *
- * @param value the value or function to persist
- */
-export function useLatestRef(value: T) {
- const ref = useRef(value);
-
- useEffect(() => {
- ref.current = value;
- }, [value]);
-
- return ref;
-}
diff --git a/src/app/common/hooks/use-media-query.ts b/src/app/common/hooks/use-media-query.ts
deleted file mode 100644
index 1d9249726cc..00000000000
--- a/src/app/common/hooks/use-media-query.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { useEffect, useState } from 'react';
-
-import { BreakpointToken, token } from 'leather-styles/tokens';
-
-function useMediaQuery(query: string) {
- const [matches, setMatches] = useState(false);
-
- useEffect(() => {
- const media = window.matchMedia(query);
- if (media.matches !== matches) {
- setMatches(media.matches);
- }
- const listener = () => setMatches(media.matches);
- window.addEventListener('resize', listener);
- return () => window.removeEventListener('resize', listener);
- }, [matches, query]);
-
- return matches;
-}
-
-export function useViewportMinWidth(viewport: BreakpointToken) {
- return useMediaQuery(`(min-width: ${token(`breakpoints.${viewport}`)})`);
-}
diff --git a/src/app/common/hooks/use-route-header.ts b/src/app/common/hooks/use-route-header.ts
deleted file mode 100644
index bd89d969d2b..00000000000
--- a/src/app/common/hooks/use-route-header.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { useEffect } from 'react';
-import { useLocation } from 'react-router-dom';
-
-import { useRouteHeaderState } from '@app/store/ui/ui.hooks';
-
-export function useRouteHeader(header: React.JSX.Element, isParentRoute?: boolean) {
- const location = useLocation();
- const [_, setRouteHeader] = useRouteHeaderState();
- useEffect(() => {
- if (location.state?.hasHeaderTitle && isParentRoute) {
- return;
- }
- setRouteHeader(header);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [location.pathname]);
-}
diff --git a/src/app/common/utils.ts b/src/app/common/utils.ts
index 8f7e1235e56..405c2982938 100644
--- a/src/app/common/utils.ts
+++ b/src/app/common/utils.ts
@@ -265,10 +265,6 @@ export function isPopupMode() {
return pageMode === 'popup';
}
-export function isFullPageMode() {
- return pageMode === 'full';
-}
-
interface WhenStacksChainIdMap {
[ChainID.Mainnet]: T;
[ChainID.Testnet]: T;
diff --git a/src/app/common/utils/copy-to-clipboard.ts b/src/app/common/utils/copy-to-clipboard.ts
new file mode 100644
index 00000000000..2ba36a7dc8d
--- /dev/null
+++ b/src/app/common/utils/copy-to-clipboard.ts
@@ -0,0 +1,6 @@
+import toast from 'react-hot-toast';
+
+export function copyToClipboard(text: string) {
+ navigator.clipboard.writeText(text);
+ toast.success('Copied to clipboard!');
+}
diff --git a/src/app/common/utils/use-interval.ts b/src/app/common/utils/use-interval.ts
deleted file mode 100644
index 84b9d19f9ab..00000000000
--- a/src/app/common/utils/use-interval.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useEffect, useRef } from 'react';
-
-import { noop } from '@shared/utils';
-
-export function useInterval(callback: () => void, delay: number | null) {
- const savedCallback = useRef(noop);
-
- // Remember the latest callback.
- useEffect(() => {
- if (savedCallback) {
- savedCallback.current = callback;
- }
- }, [callback]);
-
- // Set up the interval.
- useEffect(() => {
- function tick() {
- savedCallback.current();
- }
- if (delay !== null) {
- const id = setInterval(tick, delay);
- return () => clearInterval(id);
- }
- return;
- }, [delay]);
-}
diff --git a/src/app/common/utils/use-waiting-message.ts b/src/app/common/utils/use-waiting-message.ts
deleted file mode 100644
index 6ac9701c667..00000000000
--- a/src/app/common/utils/use-waiting-message.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { useMemo, useRef, useState } from 'react';
-
-import { useInterval } from './use-interval';
-
-// Keys are the seconds to wait before showing the message
-export type WaitingMessages = Record;
-
-function messageForSecondsPassed(waitingMessages: WaitingMessages, seconds: number) {
- return waitingMessages[seconds as keyof typeof waitingMessages];
-}
-
-export const useWaitingMessage = (
- waitingMessages: WaitingMessages,
- { waitingMessageInterval } = {
- waitingMessageInterval: 1000,
- }
-): [boolean, string, () => void, () => void] => {
- const [isRunning, setIsRunning] = useState(false);
- const [waitingMessage, setWaitingMessage] = useState(messageForSecondsPassed(waitingMessages, 0));
- const handlers = useMemo(
- () => ({
- startWaitingMessage: () => setIsRunning(true),
- stopWaitingMessage: () => setIsRunning(false),
- }),
- []
- );
- const secondsPassed = useRef(0);
-
- useInterval(
- () => {
- secondsPassed.current += waitingMessageInterval / 1000;
- const newMessage = messageForSecondsPassed(waitingMessages, secondsPassed.current);
- if (newMessage) setWaitingMessage(newMessage);
- },
- isRunning ? waitingMessageInterval : null
- );
-
- return [isRunning, waitingMessage, handlers.startWaitingMessage, handlers.stopWaitingMessage];
-};
diff --git a/src/app/components/account/account-addresses.tsx b/src/app/components/account/account-addresses.tsx
index f9c3c66b64e..f8feff13b97 100644
--- a/src/app/components/account/account-addresses.tsx
+++ b/src/app/components/account/account-addresses.tsx
@@ -1,6 +1,5 @@
import { HStack } from 'leather-styles/jsx';
-import { useViewportMinWidth } from '@app/common/hooks/use-media-query';
import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';
import { Caption } from '@app/ui/components/typography/caption';
import { truncateMiddle } from '@app/ui/utils/truncate-middle';
@@ -12,13 +11,11 @@ interface AccountAddressesProps {
index: number;
}
export function AcccountAddresses({ index }: AccountAddressesProps) {
- const isBreakpointSm = useViewportMinWidth('sm');
-
return (
- {account => {truncateMiddle(account.address, isBreakpointSm ? 4 : 3)} }
+ {account => {truncateMiddle(account.address, 4)} }
{signer => {truncateMiddle(signer.address, 5)} }
diff --git a/src/app/components/app-version.tsx b/src/app/components/app-version.tsx
index c67990f8ffe..79acf72111e 100644
--- a/src/app/components/app-version.tsx
+++ b/src/app/components/app-version.tsx
@@ -1,6 +1,6 @@
import { forwardRef, useMemo } from 'react';
-import { HTMLStyledProps, styled } from 'leather-styles/jsx';
+import { Box, HTMLStyledProps, styled } from 'leather-styles/jsx';
import { BRANCH_NAME, COMMIT_SHA } from '@shared/environment';
@@ -13,19 +13,18 @@ interface AppVersionLabelProps extends HTMLStyledProps<'span'> {
}
const AppVersionLabel = forwardRef(
({ children, isLatestVersion, ...props }: AppVersionLabelProps, ref) => (
-
- {children}
-
+
+
+ {children}
+
+
)
);
diff --git a/src/app/components/bitcoin-custom-fee/bitcoin-custom-fee.tsx b/src/app/components/bitcoin-custom-fee/bitcoin-custom-fee.tsx
index 0913027cca8..2ae4c85bbd0 100644
--- a/src/app/components/bitcoin-custom-fee/bitcoin-custom-fee.tsx
+++ b/src/app/components/bitcoin-custom-fee/bitcoin-custom-fee.tsx
@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction, useCallback, useRef } from 'react';
+import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
import { Form, Formik, useField } from 'formik';
import { Stack, styled } from 'leather-styles/jsx';
import * as yup from 'yup';
@@ -8,7 +9,7 @@ import { BtcFeeType } from '@shared/models/fees/bitcoin-fees.model';
import { createMoney } from '@shared/models/money.model';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
-import { PreviewButton } from '@app/components/preview-button';
+import { Button } from '@app/ui/components/button/button';
import { Input } from '@app/ui/components/input/input';
import { Link } from '@app/ui/components/link/link';
@@ -138,7 +139,14 @@ export function BitcoinCustomFee({
/>
-
+ props.handleSubmit}
+ type="submit"
+ >
+ Use custom fee
+
)}
diff --git a/src/app/components/broadcast-error-drawer/broadcast-error-drawer.layout.tsx b/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx
similarity index 62%
rename from src/app/components/broadcast-error-drawer/broadcast-error-drawer.layout.tsx
rename to src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx
index d6b7de7d14a..a68718d60ca 100644
--- a/src/app/components/broadcast-error-drawer/broadcast-error-drawer.layout.tsx
+++ b/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx
@@ -1,16 +1,19 @@
+import { useLocation, useNavigate } from 'react-router-dom';
+
import GenericError from '@assets/images/generic-error.png';
import { Flex, styled } from 'leather-styles/jsx';
+import get from 'lodash.get';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { Button } from '@app/ui/components/button/button';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+
+export function BroadcastErrorDialog() {
+ const navigate = useNavigate();
+ const location = useLocation();
+ const message = get(location.state, 'message', '');
-interface BroadcastErrorDrawerLayoutProps {
- message: string;
- onClose(): void;
-}
-export function BroadcastErrorDrawerLayout({ message, onClose }: BroadcastErrorDrawerLayoutProps) {
return (
- >} isShowing onClose={onClose} textAlign="center">
+ navigate('..')}>
@@ -27,10 +31,10 @@ export function BroadcastErrorDrawerLayout({ message, onClose }: BroadcastErrorD
Your transaction failed to broadcast{' '}
{message && <>because of the error: {message.toLowerCase()}>}
-
+ navigate('..')} mt="space.05">
Close
-
+
);
}
diff --git a/src/app/components/broadcast-error-drawer/broadcast-error-drawer.tsx b/src/app/components/broadcast-error-drawer/broadcast-error-drawer.tsx
deleted file mode 100644
index 576ab38bec8..00000000000
--- a/src/app/components/broadcast-error-drawer/broadcast-error-drawer.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useLocation, useNavigate } from 'react-router-dom';
-
-import get from 'lodash.get';
-
-import { BroadcastErrorDrawerLayout } from './broadcast-error-drawer.layout';
-
-export function BroadcastErrorDrawer() {
- const navigate = useNavigate();
- const location = useLocation();
-
- return (
- navigate('..')}
- />
- );
-}
diff --git a/src/app/components/centered-page-container.tsx b/src/app/components/centered-page-container.tsx
deleted file mode 100644
index fc1d1c41d95..00000000000
--- a/src/app/components/centered-page-container.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Flex, FlexProps } from 'leather-styles/jsx';
-
-export function CenteredPageContainer(props: FlexProps) {
- return (
-
- );
-}
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/choose-asset-container.tsx b/src/app/components/crypto-assets/choose-crypto-asset/choose-asset-container.tsx
index f2f213c8424..5eae0646903 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/choose-asset-container.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/choose-asset-container.tsx
@@ -9,8 +9,8 @@ export function ChooseAssetContainer({ children }: HasChildren) {
{children}
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
deleted file mode 100644
index c5c9418347b..00000000000
--- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
-import { Stack, StackProps } from 'leather-styles/jsx';
-
-export function CryptoAssetListLayout({ children }: StackProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
index b9db5559af2..75ac025b8d2 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
@@ -1,3 +1,6 @@
+import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
+import { Stack } from 'leather-styles/jsx';
+
import type { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset-balance.model';
import { StacksFungibleTokenAsset } from '@shared/models/crypto-asset.model';
@@ -10,7 +13,6 @@ import { BtcAvatarIcon } from '@app/ui/components/avatar/btc-avatar-icon';
import { CryptoCurrencyAssetItemLayout } from '../crypto-currency-asset/crypto-currency-asset-item.layout';
import { CryptoAssetListItem } from './crypto-asset-list-item';
-import { CryptoAssetListLayout } from './crypto-asset-list.layout';
interface CryptoAssetListProps {
cryptoAssetBalances: AllTransferableCryptoAssetBalances[];
@@ -20,7 +22,7 @@ export function CryptoAssetList({ cryptoAssetBalances, onItemClick }: CryptoAsse
const { whenWallet } = useWalletType();
return (
-
+
{signer => (
@@ -56,6 +58,6 @@ export function CryptoAssetList({ cryptoAssetBalances, onItemClick }: CryptoAsse
),
ledger: null,
})}
-
+
);
}
diff --git a/src/app/components/drawer/base-drawer.tsx b/src/app/components/drawer/base-drawer.tsx
deleted file mode 100644
index 0f393401cb3..00000000000
--- a/src/app/components/drawer/base-drawer.tsx
+++ /dev/null
@@ -1,127 +0,0 @@
-import { ReactNode, Suspense, memo, useCallback, useRef } from 'react';
-import { useNavigate } from 'react-router-dom';
-
-import { Box, Flex, FlexProps } from 'leather-styles/jsx';
-
-import { noop } from '@shared/utils';
-
-import { useEventListener } from '@app/common/hooks/use-event-listener';
-import { useOnClickOutside } from '@app/common/hooks/use-onclickoutside';
-
-import { DrawerHeader } from './components/drawer-header';
-
-function useDrawer(isShowing: boolean, onClose: () => void, pause?: boolean) {
- const ref = useRef(null);
-
- const handleKeyDown = useCallback(
- (e: React.KeyboardEvent) => {
- if (isShowing && e.key === 'Escape') {
- onClose();
- }
- },
- [onClose, isShowing]
- );
-
- useOnClickOutside(ref, !pause && isShowing ? onClose : null);
- useEventListener('keydown', handleKeyDown);
-
- return ref;
-}
-
-interface BaseDrawerProps extends Omit {
- children?: ReactNode;
- enableGoBack?: boolean;
- icon?: React.JSX.Element;
- isShowing: boolean;
- isWaitingOnPerformedAction?: boolean;
- onClose?(): void;
- pauseOnClickOutside?: boolean;
- title?: string;
- waitingOnPerformedActionMessage?: string;
-}
-export const BaseDrawer = memo((props: BaseDrawerProps) => {
- const {
- children,
- enableGoBack,
- icon,
- isShowing,
- isWaitingOnPerformedAction,
- onClose,
- pauseOnClickOutside,
- title,
- waitingOnPerformedActionMessage,
- ...rest
- } = props;
- const ref = useDrawer(isShowing, onClose ? onClose : noop, pauseOnClickOutside);
- const navigate = useNavigate();
-
- const onGoBack = () => navigate(-1);
-
- return (
-
-
-
-
-
- >}>{children}
-
-
-
-
- );
-});
diff --git a/src/app/components/drawer/components/drawer-header.tsx b/src/app/components/drawer/components/drawer-header.tsx
deleted file mode 100644
index c0faa9e2e2c..00000000000
--- a/src/app/components/drawer/components/drawer-header.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Box, Flex, styled } from 'leather-styles/jsx';
-import { useHover } from 'use-events';
-
-import { ArrowLeftIcon } from '@app/ui/icons/arrow-left-icon';
-import { CloseIcon } from '@app/ui/icons/close-icon';
-
-import { HeaderActionButton } from './header-action-button';
-
-interface DrawerHeaderProps {
- enableGoBack?: boolean;
- icon?: React.JSX.Element;
- isWaitingOnPerformedAction?: boolean;
- onClose?(): void;
- onGoBack(): void;
- title?: string;
- waitingOnPerformedActionMessage?: string;
-}
-export function DrawerHeader({
- enableGoBack,
- icon,
- isWaitingOnPerformedAction,
- onClose,
- onGoBack,
- title,
- waitingOnPerformedActionMessage,
-}: DrawerHeaderProps) {
- const [isHovered, bind] = useHover();
-
- return (
-
- {enableGoBack ? (
- }
- isWaitingOnPerformedAction={isWaitingOnPerformedAction}
- onAction={onGoBack}
- />
- ) : (
-
- )}
- {icon && icon}
- {title && {title} }
- {isHovered && isWaitingOnPerformedAction && (
-
- {waitingOnPerformedActionMessage}
-
- )}
- {onClose && (
- }
- isWaitingOnPerformedAction={isWaitingOnPerformedAction}
- onAction={onClose}
- />
- )}
-
- );
-}
diff --git a/src/app/components/drawer/controlled-drawer.tsx b/src/app/components/drawer/controlled-drawer.tsx
deleted file mode 100644
index 02819286cbe..00000000000
--- a/src/app/components/drawer/controlled-drawer.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { ReactNode } from 'react';
-
-import { BaseDrawer } from './base-drawer';
-
-interface ControlledDrawerProps {
- children?: ReactNode;
- enableGoBack?: boolean;
- icon?: React.JSX.Element;
- isShowing: boolean;
- onClose(): void;
- pauseOnClickOutside?: boolean;
- title?: string;
-}
-// The visibility of this drawer is controlled by an atom
-export function ControlledDrawer(props: ControlledDrawerProps) {
- const { children, enableGoBack, icon, isShowing, onClose, pauseOnClickOutside, title } = props;
-
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/components/generic-error/generic-error.tsx b/src/app/components/generic-error/generic-error.tsx
index 6c4e401f977..757458e2b39 100644
--- a/src/app/components/generic-error/generic-error.tsx
+++ b/src/app/components/generic-error/generic-error.tsx
@@ -4,9 +4,6 @@ import { FlexProps, styled } from 'leather-styles/jsx';
import { closeWindow } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
-
import { GenericErrorLayout } from './generic-error.layout';
export function GenericErrorListItem({ text }: { text: ReactNode }) {
@@ -23,8 +20,6 @@ interface GenericErrorProps extends FlexProps {
export function GenericError(props: GenericErrorProps) {
const { body, helpTextList, onClose = () => closeWindow(), title, ...rest } = props;
- useRouteHeader();
-
return (
- {onClose ? (
-
-
-
-
-
- ) : null}
- {!title && (!onClose || isBreakpointSm) ? (
-
-
- navigate(RouteUrls.Home)}
- />
-
-
-
- ) : (
-
- {title}
-
- )}
-
-
- {!hideActions && (
-
- )}
- {actionButton ? actionButton : null}
-
-
- );
-}
diff --git a/src/app/components/leather-logo.tsx b/src/app/components/leather-logo.tsx
deleted file mode 100644
index 8ec8f24dc8c..00000000000
--- a/src/app/components/leather-logo.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { memo } from 'react';
-
-import { styled } from 'leather-styles/jsx';
-
-import { LogomarkIcon } from '@app/ui/icons/logomark-icon';
-
-interface LeatherLogoProps {
- onClick?(): void;
-}
-export const LeatherLogo = memo((props: LeatherLogoProps) => {
- const { onClick } = props;
-
- return (
-
-
-
- );
-});
diff --git a/src/app/components/modal-header.tsx b/src/app/components/modal-header.tsx
deleted file mode 100644
index b1d086e90ce..00000000000
--- a/src/app/components/modal-header.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { useNavigate } from 'react-router-dom';
-
-import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors';
-import { Box, Flex, styled } from 'leather-styles/jsx';
-import { token } from 'leather-styles/tokens';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { NetworkModeBadge } from '@app/components/network-mode-badge';
-import { Button } from '@app/ui/components/button/button';
-import { ArrowLeftIcon } from '@app/ui/icons/arrow-left-icon';
-import { CloseIcon } from '@app/ui/icons/close-icon';
-
-interface ModalHeaderProps {
- actionButton?: React.JSX.Element;
- closeIcon?: boolean;
- hideActions?: boolean;
- onClose?(): void;
- onGoBack?(): void;
- defaultClose?: boolean;
- defaultGoBack?: boolean;
- title: string;
-}
-
-export function ModalHeader({
- actionButton,
- hideActions,
- onClose,
- onGoBack,
- closeIcon,
- title,
- defaultGoBack,
- defaultClose,
- ...rest
-}: ModalHeaderProps) {
- const navigate = useNavigate();
-
- function defaultCloseAction() {
- navigate(RouteUrls.Home);
- }
- function defaultGoBackAction() {
- navigate(-1);
- }
-
- const hasCloseIcon = onClose || defaultClose;
-
- return (
-
- {onGoBack || defaultGoBack ? (
-
-
-
-
-
- ) : (
-
- )}
-
-
-
- {title}
-
-
-
-
-
- {hasCloseIcon && (
-
-
-
- )}
-
-
- );
-}
diff --git a/src/app/components/network-mode-badge.tsx b/src/app/components/network-mode-badge.tsx
deleted file mode 100644
index d8067de7392..00000000000
--- a/src/app/components/network-mode-badge.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { memo, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom';
-
-import { ChainID } from '@stacks/transactions';
-import { Flex, FlexProps } from 'leather-styles/jsx';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';
-import { Tag } from '@app/ui/components/tag/tag';
-
-export const NetworkModeBadge = memo((props: FlexProps) => {
- const navigate = useNavigate();
- const { chain, name } = useCurrentNetworkState();
- const isTestnetChain = useMemo(
- () => chain.stacks.chainId === ChainID.Testnet,
- [chain.stacks.chainId]
- );
-
- if (!isTestnetChain) return null;
-
- return (
- navigate(RouteUrls.SelectNetwork, { relative: 'path' })}
- position="relative"
- zIndex={999}
- {...props}
- >
-
-
- );
-});
diff --git a/src/app/components/preview-button.tsx b/src/app/components/preview-button.tsx
deleted file mode 100644
index cf624992db5..00000000000
--- a/src/app/components/preview-button.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
-import { useFormikContext } from 'formik';
-
-import { Button } from '@app/ui/components/button/button';
-
-interface PreviewButtonProps {
- text?: string;
- isDisabled?: boolean;
-}
-export function PreviewButton({ text = 'Continue', isDisabled, ...props }: PreviewButtonProps) {
- const { handleSubmit } = useFormikContext();
-
- return (
- handleSubmit()}
- type="submit"
- {...props}
- >
- {text}
-
- );
-}
diff --git a/src/app/components/request-password.tsx b/src/app/components/request-password.tsx
index 1e87f6c88b1..69242b638fe 100644
--- a/src/app/components/request-password.tsx
+++ b/src/app/components/request-password.tsx
@@ -1,40 +1,30 @@
-import { FormEvent, ReactNode, useCallback, useState } from 'react';
+import { FormEvent, useCallback, useState } from 'react';
import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Stack, styled } from 'leather-styles/jsx';
+import { Box, styled } from 'leather-styles/jsx';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useKeyActions } from '@app/common/hooks/use-key-actions';
import { buildEnterKeyEvent } from '@app/common/hooks/use-modifier-key';
-import { WaitingMessages, useWaitingMessage } from '@app/common/utils/use-waiting-message';
import { Button } from '@app/ui/components/button/button';
+import { Footer } from '@app/ui/components/containers/footers/footer';
+import { Logo } from '@app/ui/components/logo';
+import { Card } from '@app/ui/layout/card/card';
+import { Page } from '@app/ui/layout/page/page.layout';
import { ErrorLabel } from './error-label';
-import { TwoColumnLayout } from './secret-key/two-column.layout';
-
-const waitingMessages: WaitingMessages = {
- '2': 'Verifying password…',
- '10': 'Still working…',
- '20': 'Almost there',
-};
interface RequestPasswordProps {
onSuccess(): void;
- title?: ReactNode;
- caption?: string;
}
-export function RequestPassword({ title, caption, onSuccess }: RequestPasswordProps) {
+export function RequestPassword({ onSuccess }: RequestPasswordProps) {
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const { unlockWallet } = useKeyActions();
const analytics = useAnalytics();
- const [isRunning, waitingMessage, startWaitingMessage, stopWaitingMessage] =
- useWaitingMessage(waitingMessages);
-
const submit = useCallback(async () => {
const startUnlockTimeMs = performance.now();
void analytics.track('start_unlock');
- startWaitingMessage();
setError('');
try {
await unlockWallet(password);
@@ -42,80 +32,66 @@ export function RequestPassword({ title, caption, onSuccess }: RequestPasswordPr
} catch (error) {
setError('The password you entered is invalid');
}
- stopWaitingMessage();
const unlockSuccessTimeMs = performance.now();
void analytics.track('complete_unlock', {
durationMs: unlockSuccessTimeMs - startUnlockTimeMs,
});
- }, [analytics, startWaitingMessage, stopWaitingMessage, unlockWallet, password, onSuccess]);
+ }, [analytics, unlockWallet, password, onSuccess]);
return (
- <>
-
+
-
- {title}
-
-
- {(isRunning && waitingMessage) || caption}
-
+
+
+
+ Enter your password
>
}
- rightColumn={
- <>
-
- Your password
-
-
- ) => {
- setError('');
- setPassword(e.currentTarget.value);
- }}
- onKeyUp={buildEnterKeyEvent(submit)}
- p="space.04"
- placeholder="Enter your password"
- ring="none"
- type="password"
- textStyle="body.02"
- value={password}
- width="100%"
- />
- {error && {error} }
-
+ text="Your password is used to secure your Secret Key and is only used locally on your device."
+ action={
+
}
- />
- >
+ >
+ ) => {
+ setError('');
+ setPassword(e.currentTarget.value);
+ }}
+ onKeyUp={buildEnterKeyEvent(submit)}
+ p="space.04"
+ placeholder="Enter your password"
+ ring="none"
+ type="password"
+ textStyle="body.02"
+ value={password}
+ width="100%"
+ />
+ {error && {error} }
+
+ {/* TODO: #4735 implement forgot password flow */}
+ {/*
+ Forgot password?
+ */}
+
+
);
}
diff --git a/src/app/components/secret-key/secret-key-grid.tsx b/src/app/components/secret-key/secret-key-grid.tsx
deleted file mode 100644
index c791d7acd1c..00000000000
--- a/src/app/components/secret-key/secret-key-grid.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Grid, Stack } from 'leather-styles/jsx';
-
-interface SecretKeyGridProps {
- children: React.ReactNode;
-}
-export function SecretKeyGrid({ children }: SecretKeyGridProps) {
- return (
-
-
- {children}
-
-
- );
-}
diff --git a/src/app/components/secret-key/two-column.layout.tsx b/src/app/components/secret-key/two-column.layout.tsx
deleted file mode 100644
index 7ea7e48e29e..00000000000
--- a/src/app/components/secret-key/two-column.layout.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Flex, Stack, styled } from 'leather-styles/jsx';
-
-interface TwoColumnLayoutProps {
- leftColumn: React.JSX.Element;
- rightColumn: React.JSX.Element;
-}
-
-export function TwoColumnLayout({
- leftColumn,
- rightColumn,
-}: TwoColumnLayoutProps): React.JSX.Element {
- return (
-
-
-
- {leftColumn}
-
-
-
-
-
- {rightColumn}
-
-
-
- );
-}
diff --git a/src/app/components/status-ready.tsx b/src/app/components/status-ready.tsx
index 1b28e08a11c..d0aabde4d7d 100644
--- a/src/app/components/status-ready.tsx
+++ b/src/app/components/status-ready.tsx
@@ -5,7 +5,7 @@ export function StatusReady() {
width: '8px',
height: '8px',
borderRadius: '50%',
- backgroundColor: '#23A978',
+ background: '#23A978',
}}
/>
);
diff --git a/src/app/features/activity-list/components/tab-wrapper.tsx b/src/app/features/activity-list/components/tab-wrapper.tsx
index 7d82c501831..f6b5220731b 100644
--- a/src/app/features/activity-list/components/tab-wrapper.tsx
+++ b/src/app/features/activity-list/components/tab-wrapper.tsx
@@ -10,8 +10,7 @@ export function ActivityListTabWrapper({
padContent = false,
}: ActivityListTabWrapperProps) {
return (
- // Height set based on the height of the empty assets screen
-
+
{children}
);
diff --git a/src/app/features/add-network/add-network.tsx b/src/app/features/add-network/add-network.tsx
index deba150e828..60cedfe0874 100644
--- a/src/app/features/add-network/add-network.tsx
+++ b/src/app/features/add-network/add-network.tsx
@@ -12,11 +12,8 @@ import { BitcoinNetworkModes, DefaultNetworkConfigurations } from '@shared/const
import { RouteUrls } from '@shared/route-urls';
import { isValidUrl } from '@shared/utils/validate-url';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { removeTrailingSlash } from '@app/common/url-join';
-import { CenteredPageContainer } from '@app/components/centered-page-container';
import { ErrorLabel } from '@app/components/error-label';
-import { Header } from '@app/components/header';
import {
useCurrentStacksNetworkState,
useNetworksActions,
@@ -24,6 +21,7 @@ import {
import { Button } from '@app/ui/components/button/button';
import { Input } from '@app/ui/components/input/input';
import { Title } from '@app/ui/components/typography/title';
+import { Page } from '@app/ui/layout/page/page.layout';
/**
* The **peer** network ID.
@@ -62,8 +60,6 @@ export function AddNetwork() {
const { setFieldValue } = formikProps;
- useRouteHeader( navigate(RouteUrls.Home)} />);
-
const handleApiChange = (newValue: BitcoinNetworkModes) => {
setBitcoinApi(newValue);
};
@@ -104,7 +100,7 @@ export function AddNetwork() {
}, [bitcoinApi, setStacksUrl, setBitcoinUrl]);
return (
-
+
{
@@ -205,9 +201,10 @@ export function AddNetwork() {
-
+
);
}
diff --git a/src/app/features/asset-list/asset-list.tsx b/src/app/features/asset-list/asset-list.tsx
index f8e05c26abe..f1731bd35c3 100644
--- a/src/app/features/asset-list/asset-list.tsx
+++ b/src/app/features/asset-list/asset-list.tsx
@@ -31,7 +31,7 @@ export function AssetsList() {
const { whenWallet } = useWalletType();
return (
-
+
{whenWallet({
software: (
-
+
diff --git a/src/app/features/collectibles/collectibles.tsx b/src/app/features/collectibles/collectibles.tsx
index 7f440757a5b..2cb61a05127 100644
--- a/src/app/features/collectibles/collectibles.tsx
+++ b/src/app/features/collectibles/collectibles.tsx
@@ -13,7 +13,7 @@ import { useConfigNftMetadataEnabled } from '@app/query/common/remote-config/rem
import { AddCollectible } from './components/add-collectible';
import { Ordinals } from './components/bitcoin/ordinals';
import { Stamps } from './components/bitcoin/stamps';
-import { CollectiblesLayout } from './components/collectibes.layout';
+import { CollectiblesLayout } from './components/collectible.layout';
import { StacksCryptoAssets } from './components/stacks/stacks-crypto-assets';
import { TaprootBalanceDisplayer } from './components/taproot-balance-displayer';
import { useIsFetchingCollectiblesRelatedQuery } from './hooks/use-is-fetching-collectibles';
diff --git a/src/app/features/collectibles/components/_collectible-types/collectible-other.tsx b/src/app/features/collectibles/components/_collectible-types/collectible-other.tsx
index 0f6117e9226..cd649dbb4e0 100644
--- a/src/app/features/collectibles/components/_collectible-types/collectible-other.tsx
+++ b/src/app/features/collectibles/components/_collectible-types/collectible-other.tsx
@@ -10,7 +10,7 @@ export function CollectibleOther({ children, ...props }: CollectibleOtherProps)
-
+
- {title}
+
+ {title}
+
{isLoading ? (
) : (
@@ -35,12 +37,10 @@ export function CollectiblesLayout({
{subHeader}
{children}
diff --git a/src/app/features/container/container.layout.tsx b/src/app/features/container/container.layout.tsx
deleted file mode 100644
index a3c5e99e9b8..00000000000
--- a/src/app/features/container/container.layout.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Flex } from 'leather-styles/jsx';
-
-interface ContainerLayoutProps {
- children: React.JSX.Element | React.JSX.Element[];
- header: React.JSX.Element | null;
-}
-export function ContainerLayout(props: ContainerLayoutProps) {
- const { children, header } = props;
-
- return (
-
- {header || null}
-
- {children}
-
-
- );
-}
diff --git a/src/app/features/container/container.tsx b/src/app/features/container/container.tsx
index 55d4ea9e5c8..151c67e60f3 100644
--- a/src/app/features/container/container.tsx
+++ b/src/app/features/container/container.tsx
@@ -1,26 +1,59 @@
-import { useEffect } from 'react';
-import { Toaster } from 'react-hot-toast';
-import { Outlet, useLocation } from 'react-router-dom';
+import { useEffect, useState } from 'react';
+import { Outlet, useLocation, useNavigate } from 'react-router-dom';
+import { ChainID } from '@stacks/transactions';
+import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
+import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+import { Box } from 'leather-styles/jsx';
+import { token } from 'leather-styles/tokens';
+
+import { RouteUrls } from '@shared/route-urls';
import { closeWindow } from '@shared/utils';
import { useAnalytics, useInitalizeAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { LoadingSpinner } from '@app/components/loading-spinner';
+import { CurrentAccountAvatar } from '@app/features/current-account/current-account-avatar';
+import { CurrentAccountName } from '@app/features/current-account/current-account-name';
+import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog';
+import { InAppMessages } from '@app/features/hiro-messages/in-app-messages';
import { useOnSignOut } from '@app/routes/hooks/use-on-sign-out';
import { useOnWalletLock } from '@app/routes/hooks/use-on-wallet-lock';
import { useHasStateRehydrated } from '@app/store';
-import { useRouteHeaderState } from '@app/store/ui/ui.hooks';
+import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';
+import { ContainerLayout } from '@app/ui/components/containers/container.layout';
+import { NetworkModeBadge } from '@app/ui/components/containers/headers/components/network-mode-badge';
+import { Header } from '@app/ui/components/containers/headers/header';
+import { Flag } from '@app/ui/components/flag/flag';
+import { Logo } from '@app/ui/components/logo';
+import { HamburgerIcon } from '@app/ui/icons/';
import { useRestoreFormState } from '../popup-send-form-restoration/use-restore-form-state';
-import { SettingsDropdown } from '../settings-dropdown/settings-dropdown';
-import { SwitchAccountDrawer } from '../switch-account-drawer/switch-account-drawer';
-import { ContainerLayout } from './container.layout';
+import { Settings } from '../settings/settings';
+import { TotalBalance } from './total-balance';
+import {
+ getDisplayAddresssBalanceOf,
+ isKnownPopupRoute,
+ showAccountInfo,
+} from './utils/get-popup-header';
+import { getTitleFromUrl } from './utils/get-title-from-url';
+import {
+ canGoBack,
+ getIsSessionLocked,
+ getPageVariant,
+ hideLogo,
+ isGetAddressesPopup,
+ isLandingPage,
+} from './utils/route-helpers';
export function Container() {
- const [routeHeader] = useRouteHeaderState();
- const { pathname } = useLocation();
+ const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false);
+ const navigate = useNavigate();
+ const { pathname: locationPathname } = useLocation();
+ const pathname = locationPathname as RouteUrls;
+
const analytics = useAnalytics();
const hasStateRehydrated = useHasStateRehydrated();
+ const { chain, name: chainName } = useCurrentNetworkState();
useOnWalletLock(() => closeWindow());
useOnSignOut(() => closeWindow());
@@ -29,14 +62,108 @@ export function Container() {
useEffect(() => void analytics.page('view', `${pathname}`), [analytics, pathname]);
+ const variant = getPageVariant(pathname);
+
+ useEffect(() => {
+ // set the whole body colour based on page variant so it can update dynamically
+ // TODO replace this with data-attributes to improve and fix modal BG colours
+ if (variant === 'home') {
+ document.body.style.backgroundColor = token('colors.ink.background-primary');
+ }
+ if (variant === 'page' || variant === 'onboarding') {
+ document.body.style.backgroundColor = token('colors.ink.background-secondary');
+ }
+ }, [variant, pathname]);
+
+ const displayHeader = !isLandingPage(pathname) && !isGetAddressesPopup(pathname);
+ const isSessionLocked = getIsSessionLocked(pathname);
+
+ function getOnGoBackLocation(pathname: RouteUrls) {
+ if (pathname === RouteUrls.Swap || pathname === RouteUrls.Fund) {
+ return navigate(RouteUrls.Home);
+ }
+ return navigate(-1);
+ }
+
if (!hasStateRehydrated) return ;
return (
<>
-
-
-
-
+ setIsShowingSwitchAccount(false)}
+ />
+
+
+ getOnGoBackLocation(pathname) : undefined}
+ settingsMenu={
+ isKnownPopupRoute(pathname) ? null : (
+
+ }
+ toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)}
+ />
+ )
+ }
+ networkBadge={
+
+ }
+ title={getTitleFromUrl(pathname)}
+ logo={
+ !hideLogo(pathname) && (
+
+ navigate(RouteUrls.Home) : undefined}
+ />
+
+ )
+ }
+ account={
+ showAccountInfo(pathname) && (
+
+ setIsShowingSwitchAccount(!isShowingSwitchAccount)
+ }
+ />
+ }
+ >
+
+
+ )
+ }
+ totalBalance={
+ showAccountInfo(pathname) && (
+
+ )
+ }
+ />
+ ) : null
+ }
+ variant={variant}
+ >
>
diff --git a/src/app/features/container/total-balance.tsx b/src/app/features/container/total-balance.tsx
new file mode 100644
index 00000000000..13095a54fd2
--- /dev/null
+++ b/src/app/features/container/total-balance.tsx
@@ -0,0 +1,57 @@
+import { Suspense } from 'react';
+
+import { Box, HStack } from 'leather-styles/jsx';
+
+import { BtcBalance } from '@app/components/balance-btc';
+import { StxBalance } from '@app/components/balance-stx';
+import { LoadingRectangle } from '@app/components/loading-rectangle';
+import { useConfigBitcoinEnabled } from '@app/query/common/remote-config/remote-config.query';
+import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+
+interface TotalBalanceLayoutProps {
+ children: React.ReactNode;
+}
+function TotalBalanceLayout({ children }: TotalBalanceLayoutProps) {
+ return (
+
+ {children}
+
+ );
+}
+
+interface TotalBalanceProps {
+ displayAddresssBalanceOf?: 'all' | 'stx';
+}
+
+/**
+ * #4370 This code has been ported from legacy PopupHeader to load balances
+ */
+
+function TotalBalanceSuspense({ displayAddresssBalanceOf }: TotalBalanceProps) {
+ const account = useCurrentStacksAccount();
+ const isBitcoinEnabled = useConfigBitcoinEnabled();
+ return (
+
+
+ {account && displayAddresssBalanceOf === 'stx' && }
+ {isBitcoinEnabled && displayAddresssBalanceOf === 'all' && }
+
+
+ );
+}
+
+function TotalBalanceFallback() {
+ return (
+
+
+
+ );
+}
+
+export function TotalBalance(props: TotalBalanceProps) {
+ return (
+ }>
+
+
+ );
+}
diff --git a/src/app/features/container/utils/get-popup-header.ts b/src/app/features/container/utils/get-popup-header.ts
new file mode 100644
index 00000000000..d24ea0ac2e4
--- /dev/null
+++ b/src/app/features/container/utils/get-popup-header.ts
@@ -0,0 +1,38 @@
+/**
+ * POPUP header logic notes here -> https://github.com/leather-wallet/extension/issues/4371#issuecomment-1919114939
+ */
+import { RouteUrls } from '@shared/route-urls';
+
+export function showAccountInfo(pathname: RouteUrls) {
+ return (
+ pathname === RouteUrls.TransactionRequest ||
+ pathname === RouteUrls.ProfileUpdateRequest ||
+ pathname === RouteUrls.PsbtRequest
+ );
+}
+export function getDisplayAddresssBalanceOf(pathname: RouteUrls) {
+ switch (pathname) {
+ case RouteUrls.TransactionRequest:
+ case RouteUrls.ProfileUpdateRequest:
+ case RouteUrls.PsbtRequest:
+ return 'all';
+ case RouteUrls.SignatureRequest:
+ case RouteUrls.RpcGetAddresses:
+ return undefined;
+ default:
+ return 'stx';
+ }
+}
+
+export function isKnownPopupRoute(pathname: RouteUrls) {
+ switch (pathname) {
+ case RouteUrls.TransactionRequest:
+ case RouteUrls.ProfileUpdateRequest:
+ case RouteUrls.PsbtRequest:
+ case RouteUrls.SignatureRequest:
+ case RouteUrls.RpcGetAddresses:
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/src/app/features/container/utils/get-title-from-url.ts b/src/app/features/container/utils/get-title-from-url.ts
new file mode 100644
index 00000000000..dd05c7ecea9
--- /dev/null
+++ b/src/app/features/container/utils/get-title-from-url.ts
@@ -0,0 +1,35 @@
+import { RouteUrls } from '@shared/route-urls';
+
+export function getTitleFromUrl(pathname: RouteUrls) {
+ if (pathname.match(RouteUrls.SendCryptoAsset)) {
+ // don't show send on first step of send flow
+ if (pathname === RouteUrls.SendCryptoAsset) return undefined;
+ return 'Send';
+ }
+
+ switch (pathname) {
+ case RouteUrls.AddNetwork:
+ return 'Add a network';
+ case RouteUrls.BitcoinContractList:
+ return 'Bitcoin Contracts';
+ case RouteUrls.BitcoinContractLockSuccess:
+ return 'Locked Bitcoin';
+ case RouteUrls.SendBrc20ChooseFee:
+ return 'Choose fee';
+ case RouteUrls.SendBrc20Confirmation:
+ case RouteUrls.SwapReview:
+ case RouteUrls.SendBrc20Confirmation:
+ case '/send/btc/confirm':
+ return 'Review';
+ case RouteUrls.Swap:
+ return 'Swap';
+ case RouteUrls.SentStxTxSummary:
+ case RouteUrls.SentBtcTxSummary:
+ return 'Sent';
+ case RouteUrls.SentBrc20Summary:
+ return 'Creating transfer inscription';
+ case RouteUrls.SendBrc20Confirmation:
+ default:
+ return undefined;
+ }
+}
diff --git a/src/app/features/container/utils/route-helpers.ts b/src/app/features/container/utils/route-helpers.ts
new file mode 100644
index 00000000000..9755ed10abb
--- /dev/null
+++ b/src/app/features/container/utils/route-helpers.ts
@@ -0,0 +1,49 @@
+import { RouteUrls } from '@shared/route-urls';
+
+import { isKnownPopupRoute } from './get-popup-header';
+
+function isHomePage(pathname: RouteUrls) {
+ return (
+ pathname === RouteUrls.Home ||
+ pathname.match(RouteUrls.Activity) ||
+ pathname.match(RouteUrls.Receive)
+ );
+}
+
+export function isLandingPage(pathname: RouteUrls) {
+ return pathname === RouteUrls.RequestDiagnostics || pathname.match(RouteUrls.Onboarding); // need to match get-started/ledger
+}
+
+const isOnboardingPage = (pathname: RouteUrls) => {
+ return (
+ pathname === RouteUrls.BackUpSecretKey ||
+ pathname === RouteUrls.SetPassword ||
+ pathname === RouteUrls.SignIn ||
+ pathname === RouteUrls.ViewSecretKey
+ );
+};
+
+export function getPageVariant(pathname: RouteUrls) {
+ if (isHomePage(pathname)) return 'home';
+ if (isOnboardingPage(pathname)) return 'onboarding';
+ return 'page';
+}
+
+export function getIsSessionLocked(pathname: RouteUrls) {
+ return pathname === RouteUrls.Unlock;
+}
+
+export function canGoBack(pathname: RouteUrls) {
+ if (getIsSessionLocked(pathname) || isKnownPopupRoute(pathname)) {
+ return false;
+ }
+ return true;
+}
+
+export function hideLogo(pathname: RouteUrls) {
+ return pathname === RouteUrls.RpcGetAddresses;
+}
+
+export function isGetAddressesPopup(pathname: RouteUrls) {
+ return pathname === RouteUrls.RpcGetAddresses;
+}
diff --git a/src/app/features/current-account/current-account-avatar.tsx b/src/app/features/current-account/current-account-avatar.tsx
index 39296fac380..13e7f6bb145 100644
--- a/src/app/features/current-account/current-account-avatar.tsx
+++ b/src/app/features/current-account/current-account-avatar.tsx
@@ -3,24 +3,27 @@ import { memo } from 'react';
import { CircleProps } from 'leather-styles/jsx';
import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names';
-import { useDrawers } from '@app/common/hooks/use-drawers';
-import { AccountAvatar } from '@app/components/account/account-avatar';
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
+import { AccountAvatar } from '@app/ui/components/account/account-avatar/account-avatar';
-export const CurrentAccountAvatar = memo((props: CircleProps) => {
+interface CurrentAccountAvatar extends CircleProps {
+ toggleSwitchAccount(): void;
+}
+export const CurrentAccountAvatar = memo((props: CurrentAccountAvatar) => {
+ const { toggleSwitchAccount } = props;
const accountIndex = useCurrentAccountIndex();
const accounts = useStacksAccounts();
const currentAccount = accounts[accountIndex] as StacksAccount | undefined;
const name = useCurrentAccountDisplayName();
- const { setIsShowingSwitchAccountsState } = useDrawers();
+
if (!currentAccount) return null;
return (
setIsShowingSwitchAccountsState(true)}
+ onClick={toggleSwitchAccount}
publicKey={currentAccount.stxPublicKey}
{...props}
/>
diff --git a/src/app/features/current-account/popup-header.tsx b/src/app/features/current-account/popup-header.tsx
deleted file mode 100644
index b0c2cfc9748..00000000000
--- a/src/app/features/current-account/popup-header.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Suspense } from 'react';
-
-import { Box, HStack, styled } from 'leather-styles/jsx';
-
-import { BtcBalance } from '@app/components/balance-btc';
-import { StxBalance } from '@app/components/balance-stx';
-import { LoadingRectangle } from '@app/components/loading-rectangle';
-import { NetworkModeBadge } from '@app/components/network-mode-badge';
-import { CurrentAccountAvatar } from '@app/features/current-account/current-account-avatar';
-import { CurrentAccountName } from '@app/features/current-account/current-account-name';
-import { useConfigBitcoinEnabled } from '@app/query/common/remote-config/remote-config.query';
-import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-import { Flag } from '@app/ui/components/flag/flag';
-
-interface PopupHeaderLayoutProps {
- children: React.ReactNode;
-}
-function PopupHeaderLayout({ children }: PopupHeaderLayoutProps) {
- return (
-
- {children}
-
- );
-}
-
-interface PopupHeaderProps {
- displayAddresssBalanceOf?: 'all' | 'stx';
-}
-function PopupHeaderSuspense({ displayAddresssBalanceOf = 'stx' }: PopupHeaderProps) {
- const account = useCurrentStacksAccount();
- const isBitcoinEnabled = useConfigBitcoinEnabled();
- return (
-
- }
- >
-
-
-
-
-
-
-
- {account && displayAddresssBalanceOf === 'stx' && (
-
- )}
- {isBitcoinEnabled && displayAddresssBalanceOf === 'all' && }
-
-
-
-
- );
-}
-
-function PopupHeaderFallback() {
- return (
-
-
-
- );
-}
-
-export function PopupHeader(props: PopupHeaderProps) {
- return (
- }>
-
-
- );
-}
diff --git a/src/app/features/edit-nonce-drawer/components/edit-nonce-field.tsx b/src/app/features/dialogs/edit-nonce-dialog/components/edit-nonce-field.tsx
similarity index 100%
rename from src/app/features/edit-nonce-drawer/components/edit-nonce-field.tsx
rename to src/app/features/dialogs/edit-nonce-dialog/components/edit-nonce-field.tsx
diff --git a/src/app/features/edit-nonce-drawer/components/edit-nonce-form.tsx b/src/app/features/dialogs/edit-nonce-dialog/components/edit-nonce-form.tsx
similarity index 100%
rename from src/app/features/edit-nonce-drawer/components/edit-nonce-form.tsx
rename to src/app/features/dialogs/edit-nonce-dialog/components/edit-nonce-form.tsx
diff --git a/src/app/features/edit-nonce-drawer/edit-nonce-drawer.tsx b/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx
similarity index 76%
rename from src/app/features/edit-nonce-drawer/edit-nonce-drawer.tsx
rename to src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx
index d25677dead9..7b4f3d17459 100644
--- a/src/app/features/edit-nonce-drawer/edit-nonce-drawer.tsx
+++ b/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx
@@ -8,25 +8,15 @@ import { StacksSendFormValues, StacksTransactionFormValues } from '@shared/model
import { useOnMount } from '@app/common/hooks/use-on-mount';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { Link } from '@app/ui/components/link/link';
import { EditNonceForm } from './components/edit-nonce-form';
const url = 'https://www.hiro.so/questions/transactions-advanced-settings';
-function CustomFeeMessaging() {
- return (
-
- If your transaction has been pending for a long time, its nonce might not be correct.
- openInNewTab(url)}>
- Learn more.
-
-
- );
-}
-
-export function EditNonceDrawer() {
+export function EditNonceDialog() {
const { errors, setFieldError, setFieldValue, validateField, values } = useFormikContext<
StacksSendFormValues | StacksTransactionFormValues
>();
@@ -36,7 +26,6 @@ export function EditNonceDrawer() {
const { search } = useLocation();
useOnMount(() => setLoadedNextNonce(values.nonce));
-
const onGoBack = useCallback(() => {
if (search) {
return navigate('..' + search, { replace: true });
@@ -59,11 +48,16 @@ export function EditNonceDrawer() {
}, [loadedNextNonce, onGoBack, setFieldError, setFieldValue, values.nonce]);
return (
-
+ }>
-
+
+ If your transaction has been pending for a long time, its nonce might not be correct.
+ openInNewTab(url)}>
+ Learn more.
+
+
-
+
);
}
diff --git a/src/app/features/dialogs/high-fee-dialog/high-fee-dialog.tsx b/src/app/features/dialogs/high-fee-dialog/high-fee-dialog.tsx
new file mode 100644
index 00000000000..9a6fd09cc73
--- /dev/null
+++ b/src/app/features/dialogs/high-fee-dialog/high-fee-dialog.tsx
@@ -0,0 +1,74 @@
+import { useEffect, useState } from 'react';
+
+import { useFormikContext } from 'formik';
+import { HStack, Stack } from 'leather-styles/jsx';
+
+import {
+ BitcoinSendFormValues,
+ StacksSendFormValues,
+ StacksTransactionFormValues,
+} from '@shared/models/form.model';
+
+import { openInNewTab } from '@app/common/utils/open-in-new-tab';
+import { Button } from '@app/ui/components/button/button';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Link } from '@app/ui/components/link/link';
+import { Caption } from '@app/ui/components/typography/caption';
+import { Title } from '@app/ui/components/typography/title';
+import { ErrorIcon } from '@app/ui/icons';
+
+interface HighFeeDialogProps {
+ learnMoreUrl: string;
+ isShowing?: boolean;
+}
+
+export function HighFeeDialog({ learnMoreUrl, isShowing = false }: HighFeeDialogProps) {
+ const [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation] = useState(isShowing);
+
+ useEffect(() => {
+ return () => {
+ if (isShowingHighFeeConfirmation) setIsShowingHighFeeConfirmation(false);
+ };
+ }, [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation]);
+
+ const { handleSubmit, values } = useFormikContext<
+ BitcoinSendFormValues | StacksSendFormValues | StacksTransactionFormValues
+ >();
+ return (
+ setIsShowingHighFeeConfirmation(false)}
+ >
+ {isShowingHighFeeConfirmation && (
+
+
+
+
+ Are you sure you want to pay {values.fee} {values.feeCurrency} in fees for this
+ transaction?
+
+
+
+ This action cannot be undone and the fees won't be returned, even if the transaction
+ fails.
+ openInNewTab(learnMoreUrl)} size="sm">
+ Learn more
+
+
+
+ setIsShowingHighFeeConfirmation(false)}
+ width="50%"
+ variant="outline"
+ >
+ Edit fee
+
+ handleSubmit()} width="50%" type="submit">
+ Yes, I'm sure
+
+
+
+ )}
+
+ );
+}
diff --git a/src/app/features/increase-fee-drawer/components/fee-multiplier-button.tsx b/src/app/features/dialogs/increase-fee-dialog/components/fee-multiplier-button.tsx
similarity index 100%
rename from src/app/features/increase-fee-drawer/components/fee-multiplier-button.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/fee-multiplier-button.tsx
diff --git a/src/app/features/increase-fee-drawer/components/fee-multiplier.tsx b/src/app/features/dialogs/increase-fee-dialog/components/fee-multiplier.tsx
similarity index 100%
rename from src/app/features/increase-fee-drawer/components/fee-multiplier.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/fee-multiplier.tsx
diff --git a/src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx b/src/app/features/dialogs/increase-fee-dialog/components/increase-btc-fee-form.tsx
similarity index 100%
rename from src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/increase-btc-fee-form.tsx
diff --git a/src/app/features/increase-fee-drawer/components/increase-fee-actions.tsx b/src/app/features/dialogs/increase-fee-dialog/components/increase-fee-actions.tsx
similarity index 100%
rename from src/app/features/increase-fee-drawer/components/increase-fee-actions.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/increase-fee-actions.tsx
diff --git a/src/app/features/increase-fee-drawer/components/increase-fee-field.tsx b/src/app/features/dialogs/increase-fee-dialog/components/increase-fee-field.tsx
similarity index 98%
rename from src/app/features/increase-fee-drawer/components/increase-fee-field.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/increase-fee-field.tsx
index a12414bd881..5cc073b37c1 100644
--- a/src/app/features/increase-fee-drawer/components/increase-fee-field.tsx
+++ b/src/app/features/dialogs/increase-fee-dialog/components/increase-fee-field.tsx
@@ -53,7 +53,7 @@ export function IncreaseFeeField(props: IncreaseFeeFieldProps): React.JSX.Elemen
bg="transparent"
border="default"
borderRadius="sm"
- height="64px"
+ height="inputHeight"
display="block"
p="space.04"
placeholder="Enter a custom fee"
diff --git a/src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx b/src/app/features/dialogs/increase-fee-dialog/components/increase-stx-fee-form.tsx
similarity index 100%
rename from src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx
rename to src/app/features/dialogs/increase-fee-dialog/components/increase-stx-fee-form.tsx
diff --git a/src/app/features/increase-fee-drawer/hooks/use-btc-increase-fee.ts b/src/app/features/dialogs/increase-fee-dialog/hooks/use-btc-increase-fee.ts
similarity index 100%
rename from src/app/features/increase-fee-drawer/hooks/use-btc-increase-fee.ts
rename to src/app/features/dialogs/increase-fee-dialog/hooks/use-btc-increase-fee.ts
diff --git a/src/app/features/increase-fee-drawer/hooks/use-selected-tx.ts b/src/app/features/dialogs/increase-fee-dialog/hooks/use-selected-tx.ts
similarity index 100%
rename from src/app/features/increase-fee-drawer/hooks/use-selected-tx.ts
rename to src/app/features/dialogs/increase-fee-dialog/hooks/use-selected-tx.ts
diff --git a/src/app/features/increase-fee-drawer/increase-btc-fee-drawer.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx
similarity index 69%
rename from src/app/features/increase-fee-drawer/increase-btc-fee-drawer.tsx
rename to src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx
index 16ade832348..ae67ffb5b9d 100644
--- a/src/app/features/increase-fee-drawer/increase-btc-fee-drawer.tsx
+++ b/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx
@@ -6,16 +6,10 @@ import { RouteUrls } from '@shared/route-urls';
import { useLocationStateWithCache } from '@app/common/hooks/use-location-state';
import { IncreaseBtcFeeForm } from './components/increase-btc-fee-form';
-import { IncreaseFeeDrawer } from './increase-fee-drawer';
+import { IncreaseFeeDialog } from './increase-fee-dialog';
-function useIncreaseBtcFeeDrawerState() {
- return {
- tx: useLocationStateWithCache('btcTx') as BitcoinTx,
- };
-}
-
-export function IncreaseBtcFeeDrawer() {
- const { tx } = useIncreaseBtcFeeDrawerState();
+export function IncreaseBtcFeeDialog() {
+ const tx = useLocationStateWithCache('btcTx') as BitcoinTx;
const navigate = useNavigate();
const location = useLocation();
@@ -26,7 +20,7 @@ export function IncreaseBtcFeeDrawer() {
if (!tx) return null;
return (
- }
onClose={onClose}
isShowing={location.pathname === RouteUrls.IncreaseBtcFee}
diff --git a/src/app/features/increase-fee-drawer/increase-fee-drawer.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-fee-dialog.tsx
similarity index 67%
rename from src/app/features/increase-fee-drawer/increase-fee-drawer.tsx
rename to src/app/features/dialogs/increase-fee-dialog/increase-fee-dialog.tsx
index b642400598a..09c18db32bb 100644
--- a/src/app/features/increase-fee-drawer/increase-fee-drawer.tsx
+++ b/src/app/features/dialogs/increase-fee-dialog/increase-fee-dialog.tsx
@@ -3,19 +3,24 @@ import { Outlet } from 'react-router-dom';
import { Flex, Stack } from 'leather-styles/jsx';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { Spinner } from '@app/ui/components/spinner';
import { Caption } from '@app/ui/components/typography/caption';
-interface IncreaseFeeDrawerProps {
+interface IncreaseFeeDialogProps {
feeForm: React.JSX.Element;
onClose(): void;
isShowing: boolean;
}
-export function IncreaseFeeDrawer({ feeForm, onClose, isShowing }: IncreaseFeeDrawerProps) {
+export function IncreaseFeeDialog({ feeForm, onClose, isShowing }: IncreaseFeeDialogProps) {
return (
<>
-
+ }
+ >
-
+
>
);
diff --git a/src/app/features/increase-fee-drawer/increase-fee-sent-drawer.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-fee-sent-dialog.tsx
similarity index 60%
rename from src/app/features/increase-fee-drawer/increase-fee-sent-drawer.tsx
rename to src/app/features/dialogs/increase-fee-dialog/increase-fee-sent-dialog.tsx
index 67fff526d0d..0edbf888d6e 100644
--- a/src/app/features/increase-fee-drawer/increase-fee-sent-drawer.tsx
+++ b/src/app/features/dialogs/increase-fee-dialog/increase-fee-sent-dialog.tsx
@@ -4,21 +4,26 @@ import { Flex } from 'leather-styles/jsx';
import { RouteUrls } from '@shared/route-urls';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
-export function IncreaseFeeSentDrawer() {
+export function IncreaseFeeSentDialog() {
const location = useLocation();
const navigate = useNavigate();
const isShowing = location.pathname === RouteUrls.IncreaseFeeSent;
return (
<>
- navigate(RouteUrls.Home)} title="Confirmed">
+ navigate(RouteUrls.Home)}
+ header={}
+ >
-
+
>
);
diff --git a/src/app/features/increase-fee-drawer/increase-stx-fee-drawer.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx
similarity index 90%
rename from src/app/features/increase-fee-drawer/increase-stx-fee-drawer.tsx
rename to src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx
index 9c81618759e..3d58aa05701 100644
--- a/src/app/features/increase-fee-drawer/increase-stx-fee-drawer.tsx
+++ b/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx
@@ -7,9 +7,9 @@ import { LoadingKeys, useLoading } from '@app/common/hooks/use-loading';
import { useRawTxIdState } from '@app/store/transactions/raw.hooks';
import { IncreaseStxFeeForm } from './components/increase-stx-fee-form';
-import { IncreaseFeeDrawer } from './increase-fee-drawer';
+import { IncreaseFeeDialog } from './increase-fee-dialog';
-export function IncreaseStxFeeDrawer() {
+export function IncreaseStxFeeDialog() {
const [rawTxId, setRawTxId] = useRawTxIdState();
const { isLoading, setIsIdle } = useLoading(LoadingKeys.INCREASE_FEE_DRAWER);
const navigate = useNavigate();
@@ -32,7 +32,7 @@ export function IncreaseStxFeeDrawer() {
}, [isLoading, rawTxId, setIsIdle, setRawTxId, txIdFromParams]);
return (
- }
onClose={onClose}
isShowing={location.pathname === RouteUrls.IncreaseStxFee}
diff --git a/src/app/features/leather-intro-dialog/confetti-config.ts b/src/app/features/dialogs/leather-intro-dialog/confetti-config.ts
similarity index 100%
rename from src/app/features/leather-intro-dialog/confetti-config.ts
rename to src/app/features/dialogs/leather-intro-dialog/confetti-config.ts
diff --git a/src/app/features/leather-intro-dialog/leather-intro-dialog.tsx b/src/app/features/dialogs/leather-intro-dialog/leather-intro-dialog.tsx
similarity index 90%
rename from src/app/features/leather-intro-dialog/leather-intro-dialog.tsx
rename to src/app/features/dialogs/leather-intro-dialog/leather-intro-dialog.tsx
index e6e004686fb..dc59d5f6e00 100644
--- a/src/app/features/leather-intro-dialog/leather-intro-dialog.tsx
+++ b/src/app/features/dialogs/leather-intro-dialog/leather-intro-dialog.tsx
@@ -4,8 +4,6 @@ import { Outlet, Route, useNavigate } from 'react-router-dom';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { delay } from '@app/common/utils';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
-import { useAppDispatch } from '@app/store';
-import { settingsActions } from '@app/store/settings/settings.actions';
import {
LeatherIntroDialog,
@@ -38,8 +36,6 @@ export function useLeatherIntroDialogContext() {
function LeatherIntroDialogContainer() {
const analytics = useAnalytics();
const navigate = useNavigate();
- const dispatch = useAppDispatch();
-
async function onRevealNewName() {
void analytics.track('new_brand_reveal_name');
await delay(4000);
@@ -48,7 +44,6 @@ function LeatherIntroDialogContainer() {
async function onAcceptTerms() {
void analytics.track('new_brand_accept_terms');
- dispatch(settingsActions.setHasApprovedNewBrand());
navigate('../', { replace: true });
}
diff --git a/src/app/features/leather-intro-dialog/leather-intro-steps.tsx b/src/app/features/dialogs/leather-intro-dialog/leather-intro-steps.tsx
similarity index 100%
rename from src/app/features/leather-intro-dialog/leather-intro-steps.tsx
rename to src/app/features/dialogs/leather-intro-dialog/leather-intro-steps.tsx
diff --git a/src/app/features/switch-account-drawer/components/account-list-unavailable.tsx b/src/app/features/dialogs/switch-account-dialog/components/account-list-unavailable.tsx
similarity index 100%
rename from src/app/features/switch-account-drawer/components/account-list-unavailable.tsx
rename to src/app/features/dialogs/switch-account-dialog/components/account-list-unavailable.tsx
diff --git a/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx b/src/app/features/dialogs/switch-account-dialog/components/switch-account-list-item.tsx
similarity index 95%
rename from src/app/features/switch-account-drawer/components/switch-account-list-item.tsx
rename to src/app/features/dialogs/switch-account-dialog/components/switch-account-list-item.tsx
index 384fb50567c..f71e899aee4 100644
--- a/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx
+++ b/src/app/features/dialogs/switch-account-dialog/components/switch-account-list-item.tsx
@@ -9,8 +9,7 @@ import { AccountListItemLayout } from '@app/components/account/account-list-item
import { AccountNameLayout } from '@app/components/account/account-name';
import { useNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-
-import { AccountAvatarItem } from '../../../components/account/account-avatar-item';
+import { AccountAvatarItem } from '@app/ui/components/account/account-avatar/account-avatar-item';
interface SwitchAccountListItemProps {
handleClose(): void;
diff --git a/src/app/features/switch-account-drawer/components/switch-account-list.tsx b/src/app/features/dialogs/switch-account-dialog/components/switch-account-list.tsx
similarity index 79%
rename from src/app/features/switch-account-drawer/components/switch-account-list.tsx
rename to src/app/features/dialogs/switch-account-dialog/components/switch-account-list.tsx
index 3b51ffbbda5..bf40683c526 100644
--- a/src/app/features/switch-account-drawer/components/switch-account-list.tsx
+++ b/src/app/features/dialogs/switch-account-dialog/components/switch-account-list.tsx
@@ -1,6 +1,7 @@
-import { memo } from 'react';
+import { ReactNode, memo } from 'react';
import { Virtuoso } from 'react-virtuoso';
+import { css } from 'leather-styles/css';
import { Box } from 'leather-styles/jsx';
import { useWalletType } from '@app/common/use-wallet-type';
@@ -11,16 +12,22 @@ interface SwitchAccountListProps {
handleClose(): void;
currentAccountIndex: number;
addressesNum: number;
+ footer?: ReactNode;
}
export const SwitchAccountList = memo(
({ currentAccountIndex, handleClose, addressesNum }: SwitchAccountListProps) => {
const { whenWallet } = useWalletType();
+ {
+ /* // TODO check Kyrans margin needed */
+ }
return (
(
diff --git a/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx b/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx
new file mode 100644
index 00000000000..ef853657885
--- /dev/null
+++ b/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx
@@ -0,0 +1,62 @@
+import { memo } from 'react';
+
+import { useCreateAccount } from '@app/common/hooks/account/use-create-account';
+import { useWalletType } from '@app/common/use-wallet-type';
+import { useCurrentAccountIndex } from '@app/store/accounts/account';
+import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
+import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { Button } from '@app/ui/components/button/button';
+import { Dialog, DialogProps } from '@app/ui/components/containers/dialog/dialog';
+import { Footer } from '@app/ui/components/containers/footers/footer';
+import { Header } from '@app/ui/components/containers/headers/header';
+
+import { AccountListUnavailable } from './components/account-list-unavailable';
+import { SwitchAccountList } from './components/switch-account-list';
+
+export const SwitchAccountDialog = memo(({ isShowing, onClose }: DialogProps) => {
+ const currentAccountIndex = useCurrentAccountIndex();
+ const createAccount = useCreateAccount();
+ const { whenWallet } = useWalletType();
+
+ const stacksAccounts = useStacksAccounts();
+ const bitcoinAccounts = useFilteredBitcoinAccounts();
+ const btcAddressesNum = bitcoinAccounts.length / 2;
+ const stacksAddressesNum = stacksAccounts.length;
+
+ const onCreateAccount = () => {
+ createAccount();
+ onClose();
+ };
+
+ if (isShowing && stacksAddressesNum === 0 && btcAddressesNum === 0) {
+ return ;
+ }
+ // #4370 SMELL without this early return the wallet crashes on new install with
+ // : Wallet is neither of type `ledger` nor `software`
+ // FIXME remove this when adding Create Account to Ledger in #2502 #4983
+ if (!isShowing) return null;
+
+ return (
+ }
+ isShowing={isShowing}
+ onClose={onClose}
+ footer={whenWallet({
+ software: (
+
+ onCreateAccount()}>
+ Create new account
+
+
+ ),
+ ledger: <>>,
+ })}
+ >
+
+
+ );
+});
diff --git a/src/app/features/errors/app-error-boundary.tsx b/src/app/features/errors/app-error-boundary.tsx
index f13964586c5..e0b32cee18b 100644
--- a/src/app/features/errors/app-error-boundary.tsx
+++ b/src/app/features/errors/app-error-boundary.tsx
@@ -2,8 +2,6 @@ import { Box, Stack, styled } from 'leather-styles/jsx';
import { Prism } from '@app/common/clarity-prism';
import { HasChildren } from '@app/common/has-children';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
import { ErrorBoundary, FallbackProps, useErrorHandler } from '@app/features/errors/error-boundary';
import { openGithubIssue } from '@app/features/errors/utils';
import { useErrorStackTraceState } from '@app/store/ui/ui.hooks';
@@ -13,8 +11,6 @@ import { Title } from '@app/ui/components/typography/title';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
const [value] = useErrorStackTraceState();
- useRouteHeader();
-
return (
Something went wrong
diff --git a/src/app/features/high-fee-drawer/components/high-fee-confirmation.tsx b/src/app/features/high-fee-drawer/components/high-fee-confirmation.tsx
deleted file mode 100644
index 51aaa6015b2..00000000000
--- a/src/app/features/high-fee-drawer/components/high-fee-confirmation.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { useFormikContext } from 'formik';
-import { HStack, Stack } from 'leather-styles/jsx';
-
-import {
- BitcoinSendFormValues,
- StacksSendFormValues,
- StacksTransactionFormValues,
-} from '@shared/models/form.model';
-
-import { useDrawers } from '@app/common/hooks/use-drawers';
-import { openInNewTab } from '@app/common/utils/open-in-new-tab';
-import { Button } from '@app/ui/components/button/button';
-import { Link } from '@app/ui/components/link/link';
-import { Caption } from '@app/ui/components/typography/caption';
-import { Title } from '@app/ui/components/typography/title';
-
-export function HighFeeConfirmation({ learnMoreUrl }: { learnMoreUrl: string }) {
- const { handleSubmit, values } = useFormikContext<
- BitcoinSendFormValues | StacksSendFormValues | StacksTransactionFormValues
- >();
- const { setIsShowingHighFeeConfirmation } = useDrawers();
-
- return (
-
-
- Are you sure you want to pay {values.fee} {values.feeCurrency} in fees for this transaction?
-
-
- This action cannot be undone and the fees won't be returned, even if the transaction fails.{' '}
- openInNewTab(learnMoreUrl)} size="sm">
- Learn more
-
-
-
- setIsShowingHighFeeConfirmation(false)}
- width="50%"
- variant="outline"
- >
- Edit fee
-
- handleSubmit()} width="50%" type="submit">
- Yes, I'm sure
-
-
-
- );
-}
diff --git a/src/app/features/high-fee-drawer/high-fee-drawer.tsx b/src/app/features/high-fee-drawer/high-fee-drawer.tsx
deleted file mode 100644
index fa8d6d877df..00000000000
--- a/src/app/features/high-fee-drawer/high-fee-drawer.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { useEffect } from 'react';
-
-import { useDrawers } from '@app/common/hooks/use-drawers';
-import { ControlledDrawer } from '@app/components/drawer/controlled-drawer';
-import { ErrorIcon } from '@app/ui/icons/error-icon';
-
-import { HighFeeConfirmation } from './components/high-fee-confirmation';
-
-export function HighFeeDrawer(props: { learnMoreUrl: string }) {
- const { learnMoreUrl } = props;
- const { isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation } = useDrawers();
-
- useEffect(() => {
- return () => {
- if (isShowingHighFeeConfirmation) setIsShowingHighFeeConfirmation(false);
- };
- }, [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation]);
-
- return (
- }
- isShowing={isShowingHighFeeConfirmation}
- onClose={() => setIsShowingHighFeeConfirmation(false)}
- >
- {isShowingHighFeeConfirmation && }
-
- );
-}
diff --git a/src/app/features/hiro-messages/in-app-messages.tsx b/src/app/features/hiro-messages/in-app-messages.tsx
index 1d5d0d4a547..3a74216854e 100644
--- a/src/app/features/hiro-messages/in-app-messages.tsx
+++ b/src/app/features/hiro-messages/in-app-messages.tsx
@@ -7,6 +7,7 @@ import { useDismissedMessageIds } from '@app/store/settings/settings.selectors';
import { HiroMessageItem } from './components/in-app-message-item';
+// See wallet-config.md for instructions on testing InAppMessages
export function InAppMessages(props: FlexProps) {
const messages = useRemoteLeatherMessages();
diff --git a/src/app/features/html-head/head-provider.tsx b/src/app/features/html-head/head-provider.tsx
index fb1f9680572..2b5e756b58a 100644
--- a/src/app/features/html-head/head-provider.tsx
+++ b/src/app/features/html-head/head-provider.tsx
@@ -1,12 +1,9 @@
import { Link, HeadProvider as ReastHeadProvider, Title } from 'react-head';
-import { useNewBrandApprover } from '@app/store/settings/settings.selectors';
-
export function HeadProvider() {
- const { hasApprovedNewBrand } = useNewBrandApprover();
return (
- {hasApprovedNewBrand ? : }
+
);
}
@@ -20,12 +17,3 @@ function LeatherMetaTags() {
>
);
}
-
-function HiroMetaTags() {
- return (
- <>
- Hiro Wallet
-
- >
- );
-}
diff --git a/src/app/features/ledger/components/ledger-wrapper.tsx b/src/app/features/ledger/components/ledger-wrapper.tsx
index 7f5ca90632b..07b7a82d4b0 100644
--- a/src/app/features/ledger/components/ledger-wrapper.tsx
+++ b/src/app/features/ledger/components/ledger-wrapper.tsx
@@ -6,7 +6,7 @@ interface LedgerWrapperProps extends BoxProps {
export function LedgerWrapper({ image, children, ...props }: LedgerWrapperProps) {
return (
-
+
{image && {image} }
{children}
diff --git a/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx b/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx
index c1b718944f7..d28a93ce2b7 100644
--- a/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx
+++ b/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx
@@ -16,7 +16,6 @@ import { useKeyActions } from '@app/common/hooks/use-key-actions';
import { useScrollLock } from '@app/common/hooks/use-scroll-lock';
import { makeLedgerCompatibleUnsignedAuthResponsePayload } from '@app/common/unsafe-auth-response';
import { delay } from '@app/common/utils';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import {
getStacksAppVersion,
prepareLedgerDeviceStacksAppConnection,
@@ -26,6 +25,8 @@ import {
useCurrentStacksAccount,
useStacksAccounts,
} from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { useLedgerNavigate } from '../../hooks/use-ledger-navigate';
import { checkLockedDeviceError, useLedgerResponseState } from '../../utils/generic-ledger-utils';
@@ -180,15 +181,18 @@ export function LedgerSignJwtContainer() {
return (
-
+ }
onClose={onCancelConnectLedger}
- pauseOnClickOutside
- waitingOnPerformedActionMessage="Ledger device in use"
>
-
+
);
}
diff --git a/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx b/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx
index c16b0d498f0..6554b51c2d2 100644
--- a/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx
+++ b/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { Outlet, useLocation } from 'react-router-dom';
+import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { bytesToHex, signatureVrsToRsv } from '@stacks/common';
import { serializeCV } from '@stacks/transactions';
@@ -12,7 +12,6 @@ import { isError } from '@shared/utils';
import { useScrollLock } from '@app/common/hooks/use-scroll-lock';
import { appEvents } from '@app/common/publish-subscribe';
import { delay } from '@app/common/utils';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import {
getStacksAppVersion,
prepareLedgerDeviceStacksAppConnection,
@@ -22,6 +21,8 @@ import {
} from '@app/features/ledger/utils/stacks-ledger-utils';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { useLedgerAnalytics } from '../../hooks/use-ledger-analytics.hook';
import { useLedgerNavigate } from '../../hooks/use-ledger-navigate';
@@ -50,6 +51,7 @@ function LedgerSignMsgData({ children }: LedgerSignMsgDataProps) {
type LedgerSignMsgProps = LedgerSignMsgData;
function LedgerSignStacksMsg({ account, unsignedMessage }: LedgerSignMsgProps) {
useScrollLock(true);
+ const navigate = useNavigate();
const location = useLocation();
const ledgerNavigate = useLedgerNavigate();
@@ -150,16 +152,19 @@ function LedgerSignStacksMsg({ account, unsignedMessage }: LedgerSignMsgProps) {
return (
- navigate(-1) : undefined}
isShowing
- isWaitingOnPerformedAction={awaitingDeviceConnection || canUserCancelAction}
+ header={
+
+ }
onClose={ledgerNavigate.cancelLedgerAction}
- pauseOnClickOutside
- waitingOnPerformedActionMessage="Ledger device in use"
>
-
+
);
}
diff --git a/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx b/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx
index 67b4f00dc8c..d1aaec30355 100644
--- a/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx
+++ b/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx
@@ -1,7 +1,8 @@
import { Outlet, useNavigate } from 'react-router-dom';
import { useScrollLock } from '@app/common/hooks/use-scroll-lock';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { LedgerRequestKeysContext, LedgerRequestKeysProvider } from './ledger-request-keys.context';
@@ -20,15 +21,13 @@ export function RequestKeysFlow({
return (
- }
onClose={onCancelConnectLedger ? onCancelConnectLedger : () => navigate('../')}
- pauseOnClickOutside
- waitingOnPerformedActionMessage="Ledger device in use"
>
-
+
);
}
diff --git a/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx b/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx
index ded18d87988..1dcf101f95a 100644
--- a/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx
+++ b/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx
@@ -1,8 +1,9 @@
-import { Outlet } from 'react-router-dom';
+import { Outlet, useNavigate } from 'react-router-dom';
import { useLocationState } from '@app/common/hooks/use-location-state';
import { useScrollLock } from '@app/common/hooks/use-scroll-lock';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { useActionCancellableByUser } from '../../utils/stacks-ledger-utils';
import { LedgerTxSigningContext, LedgerTxSigningProvider } from './ledger-sign-tx.context';
@@ -17,22 +18,26 @@ export function TxSigningFlow({
awaitingDeviceConnection,
closeAction,
}: TxSigningFlowProps) {
+ const navigate = useNavigate();
useScrollLock(true);
const allowUserToGoBack = useLocationState('goBack');
const canUserCancelAction = useActionCancellableByUser();
return (
- navigate(-1) : undefined}
isShowing
- isWaitingOnPerformedAction={awaitingDeviceConnection || canUserCancelAction}
+ header={
+
+ }
onClose={closeAction}
- pauseOnClickOutside
- waitingOnPerformedActionMessage="Ledger device in use"
>
-
+
);
}
diff --git a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-error.layout.tsx b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-error.layout.tsx
index 870f03076bb..a77b4b54a75 100644
--- a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-error.layout.tsx
+++ b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-error.layout.tsx
@@ -34,7 +34,7 @@ export function ConnectLedgerErrorLayout(props: ConnectLedgerErrorLayoutProps) {
const { warningText, onTryAgain, appName } = props;
return (
-
+
diff --git a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx
index 18f1987f45f..1321c5b4626 100644
--- a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx
+++ b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx
@@ -5,7 +5,7 @@ import { closeWindow } from '@shared/utils';
import { doesBrowserSupportWebUsbApi, whenPageMode } from '@app/common/utils';
import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
import { immediatelyAttemptLedgerConnection } from '../../hooks/use-when-reattempt-ledger-connection';
import { ConnectLedger } from './connect-ledger';
@@ -35,12 +35,12 @@ export function ConnectLedgerStart() {
}
return (
- navigate('../')}>
+ navigate('../')}>
connectChain('bitcoin')}
connectStacks={() => connectChain('stacks')}
showInstructions
/>
-
+
);
}
diff --git a/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx b/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx
index 7e237f351a9..749fdd460f6 100644
--- a/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx
+++ b/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx
@@ -2,8 +2,8 @@ import { useNavigate } from 'react-router-dom';
import { styled } from 'leather-styles/jsx';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { UnsupportedBrowserImg } from '@app/features/ledger/illustrations/ledger-illu-unsupported-browser';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
import { Link } from '@app/ui/components/link/link';
import { LedgerTitle } from '../../components/ledger-title';
@@ -13,16 +13,21 @@ export function UnsupportedBrowserLayout() {
const navigate = useNavigate();
return (
- navigate(-1)}>
+ navigate(-1)}>
}>
Your browser isn't supported
- {' '}
- To connect your Ledger with Leather try{' '}
- Chrome or{' '}
- Brave.
+ {'To connect your Ledger with Leather try '}
+
+ Chrome
+
+ {' or '}
+
+ Brave
+
+ .
-
+
);
}
diff --git a/src/app/features/message-signer/hash-drawer.tsx b/src/app/features/message-signer/hash-drawer.tsx
index 42a3d09b096..df9d1a53228 100644
--- a/src/app/features/message-signer/hash-drawer.tsx
+++ b/src/app/features/message-signer/hash-drawer.tsx
@@ -16,6 +16,7 @@ function ShowHashButton(props: ShowHashButtonProps) {
interface HashDrawerProps {
hash: string;
}
+
export function HashDrawer(props: HashDrawerProps) {
const { hash } = props;
const [showHash, setShowHash] = useState(false);
@@ -35,7 +36,7 @@ export function HashDrawer(props: HashDrawerProps) {
{showHash ? 'Hide hash' : 'Show hash'}
-
+
diff --git a/src/app/features/message-signer/message-preview-box.tsx b/src/app/features/message-signer/message-preview-box.tsx
index 0b7a1e4a67c..32009cb5745 100644
--- a/src/app/features/message-signer/message-preview-box.tsx
+++ b/src/app/features/message-signer/message-preview-box.tsx
@@ -8,12 +8,7 @@ interface MessageBoxProps {
}
export function MessagePreviewBox({ message, hash }: MessageBoxProps) {
return (
-
+
-
-
- Cancel
-
-
- Confirm
-
-
-
+
+
+ Cancel
+
+
+ Confirm
+
+
);
}
diff --git a/src/app/features/psbt-signer/components/psbt-signer.layout.tsx b/src/app/features/psbt-signer/components/psbt-signer.layout.tsx
deleted file mode 100644
index 1016de2b254..00000000000
--- a/src/app/features/psbt-signer/components/psbt-signer.layout.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Stack } from 'leather-styles/jsx';
-
-import { HasChildren } from '@app/common/has-children';
-
-export function PsbtSignerLayout({ children }: HasChildren) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/features/psbt-signer/psbt-signer.tsx b/src/app/features/psbt-signer/psbt-signer.tsx
index 85dc31a1fdb..ea476a82f77 100644
--- a/src/app/features/psbt-signer/psbt-signer.tsx
+++ b/src/app/features/psbt-signer/psbt-signer.tsx
@@ -5,23 +5,13 @@ import { getPsbtTxInputs, getPsbtTxOutputs } from '@shared/crypto/bitcoin/bitcoi
import { RouteUrls } from '@shared/route-urls';
import { closeWindow, isError } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { SignPsbtArgs } from '@app/common/psbt/requests';
-import { PopupHeader } from '@app/features/current-account/popup-header';
import { useOnOriginTabClose } from '@app/routes/hooks/use-on-tab-closed';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentAccountTaprootIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
+import { PopupCard } from '@app/ui/components/containers/popup/popup-card';
-import { PsbtInputsAndOutputs } from './components/psbt-inputs-and-outputs/psbt-inputs-and-outputs';
-import { PsbtInputsOutputsTotals } from './components/psbt-inputs-outputs-totals/psbt-inputs-outputs-totals';
-import { PsbtRequestActions } from './components/psbt-request-actions';
-import { PsbtRequestDetailsHeader } from './components/psbt-request-details-header';
-import { PsbtRequestDetailsLayout } from './components/psbt-request-details.layout';
-import { PsbtRequestFee } from './components/psbt-request-fee';
-import { PsbtRequestHeader } from './components/psbt-request-header';
-import { PsbtRequestRaw } from './components/psbt-request-raw';
-import { PsbtRequestSighashWarningLabel } from './components/psbt-request-sighash-warning-label';
-import { PsbtSignerLayout } from './components/psbt-signer.layout';
+import * as Psbt from './components';
import { useParsedPsbt } from './hooks/use-parsed-psbt';
import { usePsbtSigner } from './hooks/use-psbt-signer';
import { PsbtSignerContext, PsbtSignerProvider } from './psbt-signer.context';
@@ -42,8 +32,6 @@ export function PsbtSigner(props: PsbtSignerProps) {
const { address: addressTaproot } = useCurrentAccountTaprootIndexZeroSigner();
const { getRawPsbt, getPsbtAsTransaction } = usePsbtSigner();
- useRouteHeader( );
-
useOnOriginTabClose(() => closeWindow());
const psbtRaw = useMemo(() => {
@@ -91,22 +79,22 @@ export function PsbtSigner(props: PsbtSignerProps) {
shouldDefaultToAdvancedView,
};
- if (shouldDefaultToAdvancedView && psbtRaw) return ;
+ if (shouldDefaultToAdvancedView && psbtRaw) return ;
return (
-
-
-
- {isPsbtMutable ? : null}
-
-
-
- {psbtRaw ? : null}
-
-
-
-
+
+
+ {isPsbtMutable ? : null}
+
+
+
+ {psbtRaw ? : null}
+
+
+
+
diff --git a/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx b/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx
index 8bae581829b..8123674bd31 100644
--- a/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx
+++ b/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx
@@ -1,9 +1,9 @@
import { Flex, styled } from 'leather-styles/jsx';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { BtcAvatarIcon } from '@app/ui/components/avatar/btc-avatar-icon';
import { Button } from '@app/ui/components/button/button';
import { Callout } from '@app/ui/components/callout/callout';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
interface RetrieveTaprootToNativeSegwitLayoutProps {
isBroadcasting: boolean;
@@ -16,7 +16,7 @@ export function RetrieveTaprootToNativeSegwitLayout(
) {
const { onClose, onApproveTransaction, isBroadcasting, children } = props;
return (
- onClose()}>
+ onClose()}>
@@ -48,6 +48,6 @@ export function RetrieveTaprootToNativeSegwitLayout(
Retrieve bitcoin
-
+
);
}
diff --git a/src/app/features/secret-key-displayer/secret-key-displayer.tsx b/src/app/features/secret-key-displayer/secret-key-displayer.tsx
index 45282345f16..302aedb2f1d 100644
--- a/src/app/features/secret-key-displayer/secret-key-displayer.tsx
+++ b/src/app/features/secret-key-displayer/secret-key-displayer.tsx
@@ -6,12 +6,12 @@ import { RouteUrls } from '@shared/route-urls';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
-import { SecretKeyDisplayerLayout } from './secret-key-displayer.layout';
+import { SecretKeyLayout } from '../../ui/components/secret-key/secret-key.layout';
-interface SecretKeyDisplayerProps {
+interface SecretKeyProps {
secretKey: string;
}
-export const SecretKeyDisplayer = memo(({ secretKey }: SecretKeyDisplayerProps) => {
+export const SecretKey = memo(({ secretKey }: SecretKeyProps) => {
const { onCopy, hasCopied } = useClipboard(secretKey || '');
const { pathname } = useLocation();
const analytics = useAnalytics();
@@ -27,7 +27,7 @@ export const SecretKeyDisplayer = memo(({ secretKey }: SecretKeyDisplayerProps)
return (
<>
- onClick?.(e)}
- px="space.04"
- py="space.04"
- textStyle="label.02"
- width="100%"
- {...props}
- >
- {children}
-
- );
-}
diff --git a/src/app/features/settings-dropdown/components/settings-menu-wrapper.tsx b/src/app/features/settings-dropdown/components/settings-menu-wrapper.tsx
deleted file mode 100644
index dfe90672396..00000000000
--- a/src/app/features/settings-dropdown/components/settings-menu-wrapper.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { forwardRef } from 'react';
-
-import { Box, BoxProps } from 'leather-styles/jsx';
-
-interface MenuWrapperProps extends BoxProps {
- isShowing: boolean;
-}
-export const MenuWrapper = forwardRef(
- ({ isShowing, ...props }: MenuWrapperProps, ref) =>
- isShowing ? (
-
- ) : null
-);
diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx
deleted file mode 100644
index 173350a2d29..00000000000
--- a/src/app/features/settings-dropdown/settings-dropdown.tsx
+++ /dev/null
@@ -1,170 +0,0 @@
-import { useCallback, useRef } from 'react';
-import { useLocation, useNavigate } from 'react-router-dom';
-
-import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Box, Flex, HStack } from 'leather-styles/jsx';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useDrawers } from '@app/common/hooks/use-drawers';
-import { useKeyActions } from '@app/common/hooks/use-key-actions';
-import { useModifierKey } from '@app/common/hooks/use-modifier-key';
-import { useOnClickOutside } from '@app/common/hooks/use-onclickoutside';
-import { useWalletType } from '@app/common/use-wallet-type';
-import { whenPageMode } from '@app/common/utils';
-import { openInNewTab, openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
-import { Divider } from '@app/components/layout/divider';
-import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-import { useHasLedgerKeys, useLedgerDeviceTargetId } from '@app/store/ledger/ledger.selectors';
-import { useCurrentNetworkId } from '@app/store/networks/networks.selectors';
-import { Caption } from '@app/ui/components/typography/caption';
-import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
-
-import { openFeedbackDialog } from '../feedback-button/feedback-button';
-import { extractDeviceNameFromKnownTargetIds } from '../ledger/utils/generic-ledger-utils';
-import { AdvancedMenuItems } from './components/advanced-menu-items';
-import { LedgerDeviceItemRow } from './components/ledger-item-row';
-import { SettingsMenuItem as MenuItem } from './components/settings-menu-item';
-import { MenuWrapper } from './components/settings-menu-wrapper';
-
-export function SettingsDropdown() {
- const ref = useRef(null);
- const hasGeneratedWallet = !!useCurrentStacksAccount();
- const { lockWallet } = useKeyActions();
-
- const { isShowingSettings, setIsShowingSettings } = useDrawers();
- const currentNetworkId = useCurrentNetworkId();
- const navigate = useNavigate();
- const analytics = useAnalytics();
- const { walletType } = useWalletType();
- const targetId = useLedgerDeviceTargetId();
-
- const { isPressed: showAdvancedMenuOptions } = useModifierKey('alt', 120);
- const location = useLocation();
-
- const handleClose = useCallback(() => setIsShowingSettings(false), [setIsShowingSettings]);
-
- const wrappedCloseCallback = useCallback(
- (callback: () => void) => () => {
- callback();
- handleClose();
- },
- [handleClose]
- );
-
- const isLedger = useHasLedgerKeys();
-
- useOnClickOutside(ref, isShowingSettings ? handleClose : null, ['settings-menu-btn']);
-
- // RouteUrls.Activity is nested off / so we need to use a link relative to the route
- const linkRelativeType =
- location.pathname === `${RouteUrls.Home}${RouteUrls.Activity}` ? 'route' : 'path';
-
- return (
-
- {isLedger && targetId && (
-
- )}
- {hasGeneratedWallet && walletType === 'software' && (
- <>
- {
- navigate(RouteUrls.ViewSecretKey);
- })}
- >
- View Secret Key
-
- >
- )}
- {
- void analytics.track('click_change_theme_menu_item');
- navigate(RouteUrls.ChangeTheme, {
- relative: linkRelativeType,
- state: { backgroundLocation: location },
- });
- })}
- >
- Change theme
-
- {whenPageMode({
- full: null,
- popup: (
- {
- void analytics.track('click_open_in_new_tab_menu_item');
- openIndexPageInNewTab(location.pathname);
- }}
- >
-
- Open in new tab
-
-
-
- ),
- })}
- {
- openInNewTab('https://leather.gitbook.io/guides/installing/contact-support');
- })}
- >
-
- Get support
-
-
-
- openFeedbackDialog())}>Give feedback
- {hasGeneratedWallet ? : null}
- {
- void analytics.track('click_change_network_menu_item');
- navigate(RouteUrls.SelectNetwork, {
- relative: linkRelativeType,
- state: { backgroundLocation: location },
- });
- })}
- >
-
- Change network
- {currentNetworkId}
-
-
-
-
-
- {showAdvancedMenuOptions && (
-
- )}
- {hasGeneratedWallet && walletType === 'software' && (
- {
- void analytics.track('lock_session');
- void lockWallet();
- navigate(RouteUrls.Unlock);
- })}
- data-testid="settings-lock"
- >
- Lock
-
- )}
-
- navigate(RouteUrls.SignOutConfirm, {
- relative: linkRelativeType,
- state: { backgroundLocation: location },
- })
- )}
- data-testid={SettingsSelectors.SignOutListItem}
- >
- Sign out
-
-
- );
-}
diff --git a/src/app/features/settings-dropdown/components/advanced-menu-items.tsx b/src/app/features/settings/components/advanced-menu-items.tsx
similarity index 77%
rename from src/app/features/settings-dropdown/components/advanced-menu-items.tsx
rename to src/app/features/settings/components/advanced-menu-items.tsx
index 42f812a3c41..e414826d6b1 100644
--- a/src/app/features/settings-dropdown/components/advanced-menu-items.tsx
+++ b/src/app/features/settings/components/advanced-menu-items.tsx
@@ -10,10 +10,9 @@ import {
import { isNumber } from '@shared/utils';
import { Divider } from '@app/components/layout/divider';
+import { DropdownMenu } from '@app/ui/components/dropdown-menu/dropdown-menu';
import { Caption } from '@app/ui/components/typography/caption';
-import { SettingsMenuItem as MenuItem } from './settings-menu-item';
-
const isAnEmptyLogsArrayByteThreshold = 7;
function isSmallEnoughToBeConsiderdEmptyCache(logSizeInBytes?: number) {
@@ -21,12 +20,8 @@ function isSmallEnoughToBeConsiderdEmptyCache(logSizeInBytes?: number) {
return logSizeInBytes < isAnEmptyLogsArrayByteThreshold;
}
-interface AdvancedMenuItemsProps {
- closeHandler(fn: () => void): () => void;
- settingsShown: boolean;
-}
-export function AdvancedMenuItems({ closeHandler, settingsShown }: AdvancedMenuItemsProps) {
- const { result: logSizeInBytes } = useAsync(async () => getLogSizeInBytes(), [settingsShown]);
+export function AdvancedMenuItems() {
+ const { result: logSizeInBytes } = useAsync(async () => getLogSizeInBytes(), []);
const diagnosticLogText = useMemo(() => {
const noLogInfoMsg = `There are no logs cached`;
@@ -39,28 +34,28 @@ export function AdvancedMenuItems({ closeHandler, settingsShown }: AdvancedMenuI
return (
<>
- {
+ {
await copyLogsToClipboard();
toast.success('Copied to clipboard');
- })}
+ }}
>
Copy diagnostics to clipboard
Contains private wallet usage activity
-
- {
+
+ {
await clearBrowserStorageLogs();
toast.success('Diagnostic logs cleared');
- })}
+ }}
>
Clear diagnostic information
{diagnosticLogText}
-
+
>
);
diff --git a/src/app/features/settings-dropdown/components/ledger-item-row.tsx b/src/app/features/settings/components/ledger-item-row.tsx
similarity index 100%
rename from src/app/features/settings-dropdown/components/ledger-item-row.tsx
rename to src/app/features/settings/components/ledger-item-row.tsx
diff --git a/src/app/pages/select-network/components/network-list-item.layout.tsx b/src/app/features/settings/network/components/network-list-item.layout.tsx
similarity index 88%
rename from src/app/pages/select-network/components/network-list-item.layout.tsx
rename to src/app/features/settings/network/components/network-list-item.layout.tsx
index 3faf4f4c132..485e8d6f36d 100644
--- a/src/app/pages/select-network/components/network-list-item.layout.tsx
+++ b/src/app/features/settings/network/components/network-list-item.layout.tsx
@@ -5,9 +5,7 @@ import { NetworkConfiguration } from '@shared/constants';
import { getUrlHostname } from '@app/common/utils';
import { Button } from '@app/ui/components/button/button';
-import { TrashIcon } from '@app/ui/icons/trash-icon';
-
-import { NetworkStatusIndicator } from './network-status-indicator';
+import { CheckmarkIcon, CloudOffIcon, TrashIcon } from '@app/ui/icons';
interface NetworkListItemLayoutProps {
networkId: string;
@@ -37,7 +35,7 @@ export function NetworkListItemLayout({
unSelectable
? undefined
: {
- backgroundColor: 'ink.component-background-hover',
+ bg: 'ink.component-background-hover',
}
}
px="space.05"
@@ -56,7 +54,7 @@ export function NetworkListItemLayout({
{getUrlHostname(network.chain.stacks.url)}
-
+ {!isOnline ? : isActive ? : null}
{isCustom && (
}
+ isShowing={isShowing}
+ onClose={onClose}
+ footer={
+
+ {
+ addNetwork();
+ onClose();
+ }}
+ >
+ Add a network
+
+
+ }
+ >
+ {Object.keys(networks).map(id => (
+ {
+ selectNetwork(id);
+ onClose();
+ }}
+ isCustom={!defaultNetworkIds.includes(id)}
+ onRemoveNetwork={id => {
+ if (id === currentNetwork.id) networksActions.changeNetwork('mainnet');
+ removeNetwork(id);
+ }}
+ />
+ ))}
+
+ );
+}
diff --git a/src/app/features/settings/settings.tsx b/src/app/features/settings/settings.tsx
new file mode 100644
index 00000000000..a7ce6e9f329
--- /dev/null
+++ b/src/app/features/settings/settings.tsx
@@ -0,0 +1,214 @@
+import { useState } from 'react';
+import { useLocation, useNavigate } from 'react-router-dom';
+
+import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+import { css } from 'leather-styles/css';
+import { Flex, styled } from 'leather-styles/jsx';
+
+import { RouteUrls } from '@shared/route-urls';
+
+import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
+import { useKeyActions } from '@app/common/hooks/use-key-actions';
+import { useModifierKey } from '@app/common/hooks/use-modifier-key';
+import { useWalletType } from '@app/common/use-wallet-type';
+import { openInNewTab, openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
+import { AppVersion } from '@app/components/app-version';
+import { Divider } from '@app/components/layout/divider';
+import { NetworkDialog } from '@app/features/settings/network/network';
+import { SignOut } from '@app/features/settings/sign-out/sign-out-confirm';
+import { ThemeDialog } from '@app/features/settings/theme/theme-dialog';
+import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { useHasLedgerKeys, useLedgerDeviceTargetId } from '@app/store/ledger/ledger.selectors';
+import { useCurrentNetworkId } from '@app/store/networks/networks.selectors';
+import { DropdownMenu } from '@app/ui/components/dropdown-menu/dropdown-menu';
+import { Flag } from '@app/ui/components/flag/flag';
+import { Caption } from '@app/ui/components/typography/caption';
+import {
+ ExitIcon,
+ ExpandIcon,
+ ExternalLinkIcon,
+ KeyIcon,
+ LockIcon,
+ MegaphoneIcon,
+ SunInCloudIcon,
+ SupportIcon,
+ SwapIcon,
+ WorldIcon,
+} from '@app/ui/icons/';
+
+import { openFeedbackDialog } from '../feedback-button/feedback-button';
+import { extractDeviceNameFromKnownTargetIds } from '../ledger/utils/generic-ledger-utils';
+import { AdvancedMenuItems } from './components/advanced-menu-items';
+import { LedgerDeviceItemRow } from './components/ledger-item-row';
+
+interface SettingsProps {
+ triggerButton: React.ReactNode;
+ toggleSwitchAccount(): void;
+}
+export function Settings({ triggerButton, toggleSwitchAccount }: SettingsProps) {
+ const [showSignOut, setShowSignOut] = useState(false);
+ const [showChangeTheme, setShowChangeTheme] = useState(false);
+ const [showChangeNetwork, setShowChangeNetwork] = useState(false);
+ const hasGeneratedWallet = !!useCurrentStacksAccount();
+ const { lockWallet } = useKeyActions();
+
+ const currentNetworkId = useCurrentNetworkId();
+ const navigate = useNavigate();
+ const analytics = useAnalytics();
+ const { walletType } = useWalletType();
+ const targetId = useLedgerDeviceTargetId();
+
+ const location = useLocation();
+
+ const isLedger = useHasLedgerKeys();
+ const { isPressed: showAdvancedMenuOptions } = useModifierKey('alt', 120);
+
+ return (
+ <>
+
+ {triggerButton}
+
+
+
+ {isLedger && targetId && (
+
+
+
+ )}
+ {hasGeneratedWallet && (
+
+ } textStyle="label.02">
+ Switch account
+
+
+ )}
+ {hasGeneratedWallet && walletType === 'software' && (
+ navigate(RouteUrls.ViewSecretKey)}
+ >
+ } textStyle="label.02">
+ View Secret Key
+
+
+ )}
+
+ {
+ void analytics.track('click_open_in_new_tab_menu_item');
+ openIndexPageInNewTab(location.pathname);
+ }}
+ >
+ } textStyle="label.02">
+ Maximize
+
+
+
+
+ {
+ void analytics.track('click_change_network_menu_item');
+ setShowChangeNetwork(!showChangeNetwork);
+ }}
+ >
+ }>
+
+ Change network
+
+ {currentNetworkId}
+
+
+
+
+
+ {
+ void analytics.track('click_change_theme_menu_item');
+ setShowChangeTheme(!showChangeTheme);
+ }}
+ >
+ }>
+
+ Change theme
+
+
+
+
+
+
+ {
+ openInNewTab('https://leather.gitbook.io/guides/installing/contact-support');
+ }}
+ >
+ } textStyle="label.02">
+
+ Get support
+
+
+
+
+ openFeedbackDialog()}>
+ } textStyle="label.02">
+ Give feedback
+
+
+
+
+
+
+ {showAdvancedMenuOptions && }
+ {hasGeneratedWallet && walletType === 'software' && (
+ {
+ void analytics.track('lock_session');
+ void lockWallet();
+ navigate(RouteUrls.Unlock);
+ }}
+ data-testid={SettingsSelectors.LockListItem}
+ >
+ } textStyle="label.02">
+ Lock
+
+
+ )}
+
+ setShowSignOut(!showSignOut)}
+ data-testid={SettingsSelectors.SignOutListItem}
+ >
+ } textStyle="label.02">
+ Sign out
+
+
+
+
+
+
+
+ setShowSignOut(!showSignOut)} />
+ setShowChangeTheme(!showChangeTheme)}
+ />
+ setShowChangeNetwork(!showChangeNetwork)}
+ />
+ >
+ );
+}
diff --git a/src/app/features/settings/sign-out/sign-out-confirm.tsx b/src/app/features/settings/sign-out/sign-out-confirm.tsx
new file mode 100644
index 00000000000..8e1be6d51c2
--- /dev/null
+++ b/src/app/features/settings/sign-out/sign-out-confirm.tsx
@@ -0,0 +1,36 @@
+import { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+import { RouteUrls } from '@shared/route-urls';
+
+import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
+import { useKeyActions } from '@app/common/hooks/use-key-actions';
+
+import { SignOutDialog } from './sign-out';
+
+interface SignOutProps {
+ isShowing: boolean;
+ onClose(): void;
+}
+
+export function SignOut({ isShowing = false, onClose }: SignOutProps) {
+ const analytics = useAnalytics();
+
+ // TODO 4370 check if this is enough to track views of previous sign-out route
+ useEffect(() => void analytics.track('sign-out'), [analytics]);
+ const { signOut } = useKeyActions();
+ const navigate = useNavigate();
+ // FIXME same bug as SwitchAcccount dialog where we call hooks from useWalletType when no wallet yet set
+ if (!isShowing) return null;
+ return (
+ {
+ void signOut().finally(() => {
+ navigate(RouteUrls.Onboarding);
+ });
+ }}
+ onClose={onClose}
+ />
+ );
+}
diff --git a/src/app/features/settings/sign-out/sign-out.tsx b/src/app/features/settings/sign-out/sign-out.tsx
new file mode 100644
index 00000000000..a2112056695
--- /dev/null
+++ b/src/app/features/settings/sign-out/sign-out.tsx
@@ -0,0 +1,105 @@
+import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+import { useFormik } from 'formik';
+import { Flex, HStack, styled } from 'leather-styles/jsx';
+
+import { useWalletType } from '@app/common/use-wallet-type';
+import { Button } from '@app/ui/components/button/button';
+import { Callout } from '@app/ui/components/callout/callout';
+import { Dialog, DialogProps } from '@app/ui/components/containers/dialog/dialog';
+import { Footer } from '@app/ui/components/containers/footers/footer';
+import { Header } from '@app/ui/components/containers/headers/header';
+
+interface SignOutDialogProps extends DialogProps {
+ onUserDeleteWallet(): void;
+}
+export function SignOutDialog({ isShowing, onUserDeleteWallet, onClose }: SignOutDialogProps) {
+ const { whenWallet, walletType } = useWalletType();
+ const form = useFormik({
+ initialValues: {
+ confirmBackup: whenWallet({ ledger: true, software: false }),
+ confirmPasswordDisable: whenWallet({ ledger: true, software: false }),
+ },
+ onSubmit() {
+ onUserDeleteWallet();
+ },
+ });
+
+ const canSignOut = form.values.confirmBackup && form.values.confirmPasswordDisable;
+
+ return (
+ }
+ isShowing={isShowing}
+ onClose={onClose}
+ footer={
+
+
+ Cancel
+
+ canSignOut && onUserDeleteWallet()}
+ type="submit"
+ >
+ Sign out
+
+
+ }
+ >
+
+ {whenWallet({
+ software:
+ "Back up your Secret Key before signing out. You'll be asked for your Secret Key on your next login.",
+ ledger:
+ "When you sign out, you'll need to reconnect your Ledger to sign back into your wallet.",
+ })}
+
+
+
+
+
+ );
+}
diff --git a/src/app/features/theme-drawer/theme-list.tsx b/src/app/features/settings/theme/theme-dialog.tsx
similarity index 71%
rename from src/app/features/theme-drawer/theme-list.tsx
rename to src/app/features/settings/theme/theme-dialog.tsx
index 4cdd87616e7..ac2217059ab 100644
--- a/src/app/features/theme-drawer/theme-list.tsx
+++ b/src/app/features/settings/theme/theme-dialog.tsx
@@ -1,13 +1,13 @@
import { useCallback } from 'react';
-import { Flex, FlexProps } from 'leather-styles/jsx';
-
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { UserSelectedTheme, themeLabelMap, useThemeSwitcher } from '@app/common/theme-provider';
+import { Dialog, DialogProps } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { ThemeListItem } from './theme-list-item';
-export function ThemeList(props: FlexProps) {
+export function ThemeDialog({ isShowing, onClose }: DialogProps) {
const themes = Object.keys(themeLabelMap) as UserSelectedTheme[];
const analytics = useAnalytics();
const { setUserSelectedTheme } = useThemeSwitcher();
@@ -25,7 +25,11 @@ export function ThemeList(props: FlexProps) {
const { userSelectedTheme } = useThemeSwitcher();
return (
-
+ }
+ isShowing={isShowing}
+ onClose={onClose}
+ >
{themes.map(theme => (
))}
-
+
);
}
diff --git a/src/app/features/theme-drawer/theme-list-item-layout.tsx b/src/app/features/settings/theme/theme-list-item.tsx
similarity index 54%
rename from src/app/features/theme-drawer/theme-list-item-layout.tsx
rename to src/app/features/settings/theme/theme-list-item.tsx
index 716e05ea1ee..33c72298fd9 100644
--- a/src/app/features/theme-drawer/theme-list-item-layout.tsx
+++ b/src/app/features/settings/theme/theme-list-item.tsx
@@ -1,17 +1,21 @@
+import { useCallback } from 'react';
+
import { Box, Flex, styled } from 'leather-styles/jsx';
-import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
+import { UserSelectedTheme, getThemeLabel } from '@app/common/theme-provider';
+import { CheckmarkIcon } from '@app/ui/icons';
interface ThemeListItemProps {
- themeLabel: string;
+ theme: UserSelectedTheme;
+ onThemeSelected(theme: UserSelectedTheme): void;
isActive: boolean;
- onThemeItemSelect(): void;
}
-export function ThemeListItemLayout({
- themeLabel,
- isActive,
- onThemeItemSelect,
-}: ThemeListItemProps) {
+export function ThemeListItem({ theme, onThemeSelected, isActive }: ThemeListItemProps) {
+ const themeLabel = getThemeLabel(theme);
+ const onThemeItemSelect = useCallback(() => {
+ onThemeSelected(theme);
+ }, [onThemeSelected, theme]);
+
return (
);
useOnOriginTabClose(() => closeWindow());
if (!tabId) return null;
diff --git a/src/app/features/stacks-transaction-request/hooks/use-stacks-transaction-summary.ts b/src/app/features/stacks-transaction-request/hooks/use-stacks-transaction-summary.ts
index bdcab79db67..309f3b9acca 100644
--- a/src/app/features/stacks-transaction-request/hooks/use-stacks-transaction-summary.ts
+++ b/src/app/features/stacks-transaction-request/hooks/use-stacks-transaction-summary.ts
@@ -34,7 +34,6 @@ export function useStacksTransactionSummary(token: CryptoCurrencies) {
function formSentSummaryTxState(txId: string, signedTx: StacksTransaction, decimals?: number) {
return {
state: {
- hasHeaderTitle: true,
txLink: {
blockchain: 'stacks',
txid: txId || '',
diff --git a/src/app/features/stacks-transaction-request/stacks-transaction-signer.tsx b/src/app/features/stacks-transaction-request/stacks-transaction-signer.tsx
index 96fdb31a3f1..f3383c43070 100644
--- a/src/app/features/stacks-transaction-request/stacks-transaction-signer.tsx
+++ b/src/app/features/stacks-transaction-request/stacks-transaction-signer.tsx
@@ -1,3 +1,4 @@
+import { useState } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { StacksTransaction } from '@stacks/transactions';
@@ -12,14 +13,12 @@ import { RouteUrls } from '@shared/route-urls';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useOnMount } from '@app/common/hooks/use-on-mount';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { stxToMicroStx } from '@app/common/money/unit-conversion';
import { stxFeeValidator } from '@app/common/validation/forms/fee-validators';
import { nonceValidator } from '@app/common/validation/nonce-validators';
import { NonceSetter } from '@app/components/nonce-setter';
-import { PopupHeader } from '@app/features/current-account/popup-header';
+import { HighFeeDialog } from '@app/features/dialogs/high-fee-dialog/high-fee-dialog';
import { RequestingTabClosedWarningMessage } from '@app/features/errors/requesting-tab-closed-error-msg';
-import { HighFeeDrawer } from '@app/features/high-fee-drawer/high-fee-drawer';
import { ContractCallDetails } from '@app/features/stacks-transaction-request/contract-call-details/contract-call-details';
import { ContractDeployDetails } from '@app/features/stacks-transaction-request/contract-deploy-details/contract-deploy-details';
import { PageTop } from '@app/features/stacks-transaction-request/page-top';
@@ -52,6 +51,7 @@ export function StacksTransactionSigner({
onSignStacksTransaction,
isMultisig,
}: StacksTransactionSignerProps) {
+ const [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation] = useState(false);
const transactionRequest = useTransactionRequestState();
const { data: stxFees } = useCalculateStacksTxFees(stacksTransaction);
const analytics = useAnalytics();
@@ -60,8 +60,6 @@ export function StacksTransactionSigner({
const { data: nextNonce } = useNextNonce();
const { search } = useLocation();
- useRouteHeader( );
-
useOnMount(() => {
void analytics.track('view_transaction_signing'), [analytics];
});
@@ -133,8 +131,13 @@ export function StacksTransactionSigner({
)}
-
-
+ setIsShowingHighFeeConfirmation(true)}
+ />
+
>
)}
diff --git a/src/app/features/stacks-transaction-request/submit-action.tsx b/src/app/features/stacks-transaction-request/submit-action.tsx
index 85c7b757881..45fc22d70e3 100644
--- a/src/app/features/stacks-transaction-request/submit-action.tsx
+++ b/src/app/features/stacks-transaction-request/submit-action.tsx
@@ -5,14 +5,16 @@ import { HIGH_FEE_AMOUNT_STX } from '@shared/constants';
import { StacksTransactionFormValues } from '@shared/models/form.model';
import { isEmpty } from '@shared/utils';
-import { useDrawers } from '@app/common/hooks/use-drawers';
import { useTransactionError } from '@app/features/stacks-transaction-request/hooks/use-transaction-error';
import { Button } from '@app/ui/components/button/button';
-export function SubmitAction() {
+interface SubmitActionProps {
+ setIsShowingHighFeeConfirmation(): void;
+}
+export function SubmitAction({ setIsShowingHighFeeConfirmation }: SubmitActionProps) {
const { handleSubmit, values, validateForm, isSubmitting } =
useFormikContext();
- const { isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation } = useDrawers();
+
const error = useTransactionError();
const isDisabled = !!error || Number(values.fee) < 0;
@@ -21,7 +23,7 @@ export function SubmitAction() {
// Check for errors before showing the high fee confirmation
const formErrors = await validateForm();
if (isEmpty(formErrors) && Number(values.fee) > HIGH_FEE_AMOUNT_STX) {
- return setIsShowingHighFeeConfirmation(!isShowingHighFeeConfirmation);
+ return setIsShowingHighFeeConfirmation();
}
handleSubmit();
};
diff --git a/src/app/features/stacks-transaction-request/transaction-error/error-messages.tsx b/src/app/features/stacks-transaction-request/transaction-error/error-messages.tsx
index 2c2d0c0b984..f88783c820f 100644
--- a/src/app/features/stacks-transaction-request/transaction-error/error-messages.tsx
+++ b/src/app/features/stacks-transaction-request/transaction-error/error-messages.tsx
@@ -1,4 +1,4 @@
-import { memo } from 'react';
+import { memo, useState } from 'react';
import { Navigate } from 'react-router-dom';
import { STXTransferPayload, TransactionTypes } from '@stacks/connect';
@@ -8,9 +8,9 @@ import { RouteUrls } from '@shared/route-urls';
import { closeWindow } from '@shared/utils';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useDrawers } from '@app/common/hooks/use-drawers';
import { useScrollLock } from '@app/common/hooks/use-scroll-lock';
import { stacksValue } from '@app/common/stacks-utils';
+import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog';
import { ErrorMessage } from '@app/features/stacks-transaction-request/transaction-error/error-message';
import { useCurrentStacksAccountBalances } from '@app/query/stacks/balance/stx-balance.hooks';
import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';
@@ -24,7 +24,7 @@ interface InsufficientFundsActionButtonsProps {
}
function InsufficientFundsActionButtons({ eventName }: InsufficientFundsActionButtonsProps) {
const analytics = useAnalytics();
- const { setIsShowingSwitchAccountsState } = useDrawers();
+ const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false);
const onGetStx = () => {
void analytics.track(eventName);
@@ -34,8 +34,12 @@ function InsufficientFundsActionButtons({ eventName }: InsufficientFundsActionBu
return (
<>
+ setIsShowingSwitchAccount(false)}
+ />
Get STX
- setIsShowingSwitchAccountsState(true)} variant="outline">
+ setIsShowingSwitchAccount(true)} variant="outline">
Switch account
>
diff --git a/src/app/features/switch-account-drawer/components/create-account-action.tsx b/src/app/features/switch-account-drawer/components/create-account-action.tsx
deleted file mode 100644
index c3de671b39b..00000000000
--- a/src/app/features/switch-account-drawer/components/create-account-action.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Flex } from 'leather-styles/jsx';
-
-import { Button } from '@app/ui/components/button/button';
-
-interface CreateAccountActionProps {
- onCreateAccount(): void;
-}
-export function CreateAccountAction({ onCreateAccount }: CreateAccountActionProps) {
- return (
-
- onCreateAccount()}>
- Create new account
-
-
- );
-}
diff --git a/src/app/features/switch-account-drawer/switch-account-drawer.tsx b/src/app/features/switch-account-drawer/switch-account-drawer.tsx
deleted file mode 100644
index 765fdef4070..00000000000
--- a/src/app/features/switch-account-drawer/switch-account-drawer.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { memo } from 'react';
-
-import { Box } from 'leather-styles/jsx';
-
-import { useCreateAccount } from '@app/common/hooks/account/use-create-account';
-import { useWalletType } from '@app/common/use-wallet-type';
-import { ControlledDrawer } from '@app/components/drawer/controlled-drawer';
-import { useCurrentAccountIndex } from '@app/store/accounts/account';
-import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
-import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-import { useShowSwitchAccountsState } from '@app/store/ui/ui.hooks';
-
-import { AccountListUnavailable } from './components/account-list-unavailable';
-import { CreateAccountAction } from './components/create-account-action';
-import { SwitchAccountList } from './components/switch-account-list';
-
-export const SwitchAccountDrawer = memo(() => {
- const [isShowing, setShowSwitchAccountsState] = useShowSwitchAccountsState();
-
- const currentAccountIndex = useCurrentAccountIndex();
- const createAccount = useCreateAccount();
- const { whenWallet } = useWalletType();
-
- const stacksAccounts = useStacksAccounts();
- const bitcoinAccounts = useFilteredBitcoinAccounts();
- const btcAddressesNum = bitcoinAccounts.length / 2;
- const stacksAddressesNum = stacksAccounts.length;
-
- const onClose = () => setShowSwitchAccountsState(false);
-
- const onCreateAccount = () => {
- createAccount();
- setShowSwitchAccountsState(false);
- };
-
- if (isShowing && stacksAddressesNum === 0 && btcAddressesNum === 0) {
- return ;
- }
-
- return isShowing ? (
-
-
-
- {whenWallet({
- software: ,
- ledger: <>>,
- })}
-
-
- ) : null;
-});
diff --git a/src/app/features/theme-drawer/theme-drawer.tsx b/src/app/features/theme-drawer/theme-drawer.tsx
deleted file mode 100644
index 52c68d3627f..00000000000
--- a/src/app/features/theme-drawer/theme-drawer.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { useNavigate } from 'react-router-dom';
-
-import { useLocationState } from '@app/common/hooks/use-location-state';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
-import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
-
-import { ThemeList } from './theme-list';
-
-export function ThemesDrawer() {
- useBackgroundLocationRedirect();
- const navigate = useNavigate();
- const backgroundLocation = useLocationState('backgroundLocation');
- return (
- navigate(backgroundLocation ?? '..')}>
-
-
- );
-}
diff --git a/src/app/features/theme-drawer/theme-list-item.tsx b/src/app/features/theme-drawer/theme-list-item.tsx
deleted file mode 100644
index 6437bda0a9e..00000000000
--- a/src/app/features/theme-drawer/theme-list-item.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useCallback } from 'react';
-
-import { UserSelectedTheme, getThemeLabel } from '@app/common/theme-provider';
-
-import { ThemeListItemLayout } from './theme-list-item-layout';
-
-interface ThemeListItemProps {
- theme: UserSelectedTheme;
- onThemeSelected(theme: UserSelectedTheme): void;
- isActive: boolean;
-}
-export function ThemeListItem({ theme, onThemeSelected, isActive }: ThemeListItemProps) {
- const themeLabel = getThemeLabel(theme);
- const itemSelectHandler = useCallback(() => {
- onThemeSelected(theme);
- }, [onThemeSelected, theme]);
-
- return (
-
- );
-}
diff --git a/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx b/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx
index ba8eb71cd97..de64497e615 100644
--- a/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx
+++ b/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx
@@ -1,6 +1,6 @@
import { useState } from 'react';
-import { Flex, styled } from 'leather-styles/jsx';
+import { Flex, Stack, styled } from 'leather-styles/jsx';
import {
BitcoinContractListItem,
@@ -11,7 +11,6 @@ import { FullPageLoadingSpinner } from '@app/components/loading-spinner';
import { truncateMiddle } from '@app/ui/utils/truncate-middle';
import { BitcoinContractListItemLayout } from './components/bitcoin-contract-list-item-layout';
-import { BitcoinContractListLayout } from './components/bitcoin-contract-list-layout';
export function BitcoinContractList() {
const { getAllActiveBitcoinContracts } = useBitcoinContracts();
@@ -36,7 +35,7 @@ export function BitcoinContractList() {
if (isLoading) return ;
return (
-
+
{bitcoinContracts.length === 0 || isError ? (
@@ -58,6 +57,6 @@ export function BitcoinContractList() {
);
})
)}
-
+
);
}
diff --git a/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-item-layout.tsx b/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-item-layout.tsx
index 12fb05fa080..3d5d9161ed9 100644
--- a/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-item-layout.tsx
+++ b/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-item-layout.tsx
@@ -38,7 +38,7 @@ export function BitcoinContractListItemLayout({
return (
handleOpenTxLink({
txid,
diff --git a/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-layout.tsx b/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-layout.tsx
deleted file mode 100644
index 3074f22f036..00000000000
--- a/src/app/pages/bitcoin-contract-list/components/bitcoin-contract-list-layout.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { ReactNode } from 'react';
-import { useNavigate } from 'react-router-dom';
-
-import { Stack } from 'leather-styles/jsx';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
-
-interface BitcoinContractListProps {
- children: ReactNode;
-}
-export function BitcoinContractListLayout({ children }: BitcoinContractListProps) {
- const navigate = useNavigate();
- useRouteHeader( navigate(RouteUrls.Home)} />);
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx b/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx
index 46150148e84..9b8904170f2 100644
--- a/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx
+++ b/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx
@@ -13,11 +13,11 @@ import {
import { useOnMount } from '@app/common/hooks/use-on-mount';
import { initialSearchParams } from '@app/common/initial-search-params';
import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
+import { PopupCard } from '@app/ui/components/containers/popup/popup-card';
import { BitcoinContractOfferDetailsSimple } from './components/bitcoin-contract-offer/bitcoin-contract-offer-details';
import { BitcoinContractRequestActions } from './components/bitcoin-contract-request-actions';
import { BitcoinContractRequestHeader } from './components/bitcoin-contract-request-header';
-import { BitcoinContractRequestLayout } from './components/bitcoin-contract-request-layout';
import { BitcoinContractRequestWarningLabel } from './components/bitcoin-contract-request-warning-label';
export function BitcoinContractRequest() {
@@ -103,7 +103,7 @@ export function BitcoinContractRequest() {
return (
<>
{!isLoading && bitcoinAddress && bitcoinContractOfferDetails && (
-
+
-
+
@@ -130,7 +130,7 @@ export function BitcoinContractRequest() {
bitcoinAddress={bitcoinAddress}
bitcoinContractOffer={bitcoinContractOfferDetails.simplifiedBitcoinContract}
/>
-
+
)}
>
);
diff --git a/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-actions.tsx b/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-actions.tsx
index 10a34eafb81..05e86cffa8c 100644
--- a/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-actions.tsx
+++ b/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-actions.tsx
@@ -1,8 +1,8 @@
import { BitcoinContractRequestSelectors } from '@tests/selectors/bitcoin-contract-request.selectors';
-import { Box, HStack } from 'leather-styles/jsx';
import { useBtcAssetBalance } from '@app/common/hooks/balance/btc/use-btc-balance';
import { Button } from '@app/ui/components/button/button';
+import { Footer } from '@app/ui/components/containers/footers/footer';
interface BitcoinContractRequestActionsProps {
isLoading: boolean;
@@ -22,35 +22,24 @@ export function BitcoinContractRequestActions({
const canAccept = btcAvailableAssetBalance.balance.amount.isGreaterThan(requiredAmount);
return (
-
-
-
- Reject
-
-
- Accept
-
-
-
+
+
+ Reject
+
+
+ Accept
+
+
);
}
diff --git a/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-layout.tsx b/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-layout.tsx
deleted file mode 100644
index 171c52142ab..00000000000
--- a/src/app/pages/bitcoin-contract-request/components/bitcoin-contract-request-layout.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Stack } from 'leather-styles/jsx';
-
-interface BitcoinContractRequestLayoutProps {
- children: React.ReactNode;
-}
-export function BitcoinContractRequestLayout({ children }: BitcoinContractRequestLayoutProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/pages/choose-account/choose-account.tsx b/src/app/pages/choose-account/choose-account.tsx
index 90f75fe195c..2f36a4050ad 100644
--- a/src/app/pages/choose-account/choose-account.tsx
+++ b/src/app/pages/choose-account/choose-account.tsx
@@ -7,7 +7,6 @@ import { closeWindow } from '@shared/utils';
import { useCancelAuthRequest } from '@app/common/authentication/use-cancel-auth-request';
import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { RequesterFlag } from '@app/components/requester-flag';
import { ChooseAccountsList } from '@app/pages/choose-account/components/accounts';
import { useOnOriginTabClose } from '@app/routes/hooks/use-on-tab-closed';
@@ -18,7 +17,6 @@ export const ChooseAccount = memo(() => {
const cancelAuthentication = useCancelAuthRequest();
- useRouteHeader(<>>);
useOnOriginTabClose(() => closeWindow());
const handleUnmount = async () => cancelAuthentication();
diff --git a/src/app/pages/choose-account/components/accounts.tsx b/src/app/pages/choose-account/components/accounts.tsx
index c7b957d5cd1..432f58fe5d9 100644
--- a/src/app/pages/choose-account/components/accounts.tsx
+++ b/src/app/pages/choose-account/components/accounts.tsx
@@ -13,12 +13,12 @@ import { useWalletType } from '@app/common/use-wallet-type';
import { slugify } from '@app/common/utils';
import { AccountTotalBalance } from '@app/components/account-total-balance';
import { AcccountAddresses } from '@app/components/account/account-addresses';
-import { AccountAvatar } from '@app/components/account/account-avatar';
import { AccountListItemLayout } from '@app/components/account/account-list-item.layout';
import { usePressable } from '@app/components/item-hover';
import { useNativeSegwitAccountIndexAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
+import { AccountAvatar } from '@app/ui/components/account/account-avatar/account-avatar';
import { PlusIcon } from '@app/ui/icons/plus-icon';
interface AccountTitlePlaceholderProps {
diff --git a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx
index 3745bd094c2..6e7e09e096e 100644
--- a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx
+++ b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx
@@ -6,12 +6,10 @@ import { RouteUrls } from '@shared/route-urls';
import { isDefined } from '@shared/utils';
import { useStxCryptoCurrencyAssetBalance } from '@app/common/hooks/balance/stx/use-stx-crypto-currency-asset-balance';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useWalletType } from '@app/common/use-wallet-type';
import { ChooseAssetContainer } from '@app/components/crypto-assets/choose-crypto-asset/choose-asset-container';
import { ChooseCryptoAssetLayout } from '@app/components/crypto-assets/choose-crypto-asset/choose-crypto-asset.layout';
import { CryptoAssetList } from '@app/components/crypto-assets/choose-crypto-asset/crypto-asset-list';
-import { ModalHeader } from '@app/components/modal-header';
import { useCheckLedgerBlockchainAvailable } from '@app/store/accounts/blockchain/utils';
export function ChooseCryptoAssetToFund() {
@@ -33,8 +31,6 @@ export function ChooseCryptoAssetToFund() {
[stxCryptoCurrencyAssetBalance, checkBlockchainAvailable, whenWallet]
);
- useRouteHeader( navigate(RouteUrls.Home)} title=" " />);
-
const navigateToSendForm = useCallback(
(cryptoAssetBalance: AllTransferableCryptoAssetBalances) => {
const { asset } = cryptoAssetBalance;
diff --git a/src/app/pages/fund/components/fund-account-tile.tsx b/src/app/pages/fund/components/fund-account-tile.tsx
index 2396a3a7552..fb74e6820d5 100644
--- a/src/app/pages/fund/components/fund-account-tile.tsx
+++ b/src/app/pages/fund/components/fund-account-tile.tsx
@@ -25,7 +25,7 @@ export function FundAccountTile(props: FundAccountTileProps) {
cursor: 'pointer',
}}
border="default"
- backgroundColor="ink.background-primary"
+ bg="ink.background-primary"
borderRadius="xs"
boxShadow="0px 1px 2px rgba(0, 0, 0, 0.04)"
data-testid={testId}
diff --git a/src/app/pages/fund/components/fund.layout.tsx b/src/app/pages/fund/components/fund.layout.tsx
index 3e5e1434c80..80b2a63fa68 100644
--- a/src/app/pages/fund/components/fund.layout.tsx
+++ b/src/app/pages/fund/components/fund.layout.tsx
@@ -1,4 +1,4 @@
-import { Flex, Stack, styled } from 'leather-styles/jsx';
+import { Stack, styled } from 'leather-styles/jsx';
import { CryptoCurrencies } from '@shared/models/currencies.model';
@@ -23,40 +23,32 @@ export function FundLayout({ symbol, children }: FundLayoutProps) {
const name = nameMap[symbol].name;
const nameAbbr = nameMap[symbol].symbol;
return (
-
-
-
- Let's get funds into your wallet
-
+ Let's get BTC
+ into your wallet
+
-
- Choose an exchange to fund your account with {name} ({nameAbbr}) or deposit from
- elsewhere. Exchanges with “Fast checkout” make it easier to purchase {nameAbbr} for direct
- deposit into your wallet with a credit card.
-
-
+
+ Choose an exchange to fund your account with {name} ({nameAbbr}) or deposit from elsewhere.
+ Exchanges with “Fast checkout” make it easier to purchase {nameAbbr} for direct deposit into
+ your wallet with a credit card.
+
{children}
-
+
);
}
diff --git a/src/app/pages/fund/fiat-providers-list.tsx b/src/app/pages/fund/fiat-providers-list.tsx
index 67c7680a46e..446abe09cf3 100644
--- a/src/app/pages/fund/fiat-providers-list.tsx
+++ b/src/app/pages/fund/fiat-providers-list.tsx
@@ -48,22 +48,10 @@ export function FiatProvidersList(props: FiatProvidersProps) {
return (
navigate(RouteUrls.FundChooseCurrency)} title=" " />);
-
if (!address || !balance) return ;
return (
<>
diff --git a/src/app/pages/home/components/account-actions.tsx b/src/app/pages/home/components/account-actions.tsx
index 02ac19609f8..11440c54378 100644
--- a/src/app/pages/home/components/account-actions.tsx
+++ b/src/app/pages/home/components/account-actions.tsx
@@ -2,7 +2,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { ChainID } from '@stacks/transactions';
import { HomePageSelectors } from '@tests/selectors/home.selectors';
-import { Flex, FlexProps } from 'leather-styles/jsx';
+import { Flex } from 'leather-styles/jsx';
import { RouteUrls } from '@shared/route-urls';
@@ -11,12 +11,12 @@ import { useConfigBitcoinEnabled } from '@app/query/common/remote-config/remote-
import { useCurrentAccountNativeSegwitIndexZeroSignerNullable } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
+import { ActionButton } from '@app/ui/components/account/action-button';
import { CreditCardIcon, InboxIcon, SwapIcon } from '@app/ui/icons';
-import { ActionButton } from './action-button';
import { SendButton } from './send-button';
-export function AccountActions(props: FlexProps) {
+export function AccountActions() {
const navigate = useNavigate();
const location = useLocation();
const isBitcoinEnabled = useConfigBitcoinEnabled();
@@ -30,7 +30,7 @@ export function AccountActions(props: FlexProps) {
: `${RouteUrls.Home}${RouteUrls.ReceiveStx}`;
return (
-
+
{
- const currentAccount = useCurrentStacksAccount();
- const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero();
-
- if (!currentAccount) return null;
- return (
-
-
-
-
-
-
-
-
-
- );
-});
diff --git a/src/app/pages/home/components/account-info-card.tsx b/src/app/pages/home/components/account-info-card.tsx
deleted file mode 100644
index 9a0e2ff6059..00000000000
--- a/src/app/pages/home/components/account-info-card.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Box, Divider, Flex, styled } from 'leather-styles/jsx';
-
-import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names';
-import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance';
-import { useDrawers } from '@app/common/hooks/use-drawers';
-import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
-import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-import { Link } from '@app/ui/components/link/link';
-import { ChevronDownIcon } from '@app/ui/icons/chevron-down-icon';
-
-import { AccountActions } from './account-actions';
-
-export function AccountInfoCard() {
- const name = useCurrentAccountDisplayName();
-
- const account = useCurrentStacksAccount();
- const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero();
- const totalBalance = useTotalBalance({ btcAddress, stxAddress: account?.address || '' });
-
- const { setIsShowingSwitchAccountsState } = useDrawers();
-
- return (
-
- setIsShowingSwitchAccountsState(true)}
- >
-
-
- {name}
-
-
-
-
-
-
-
-
- {totalBalance?.totalUsdBalance}
-
-
-
-
-
-
- );
-}
diff --git a/src/app/pages/home/components/home-tabs.tsx b/src/app/pages/home/components/home-tabs.tsx
index f19f8ba83e8..23b1c1a8ae0 100644
--- a/src/app/pages/home/components/home-tabs.tsx
+++ b/src/app/pages/home/components/home-tabs.tsx
@@ -11,7 +11,7 @@ import { Tabs } from '@app/ui/components/tabs/tabs';
interface HomeTabsProps {
children: React.ReactNode;
}
-// TODO #4013: Abstract this to generic RouteTab once choose-fee-tab updated
+
export function HomeTabs({ children }: HomeTabsProps) {
const navigate = useNavigate();
const location = useLocation();
@@ -23,13 +23,15 @@ export function HomeTabs({ children }: HomeTabsProps) {
Assets
-
+
Activity
}>
- {children}
+
+ {children}
+
);
diff --git a/src/app/pages/home/components/home.layout.tsx b/src/app/pages/home/components/home.layout.tsx
deleted file mode 100644
index cb10533830d..00000000000
--- a/src/app/pages/home/components/home.layout.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react';
-
-import { HomePageSelectors } from '@tests/selectors/home.selectors';
-import { Stack } from 'leather-styles/jsx';
-
-import { AccountInfoCard } from './account-info-card';
-
-type HomeLayoutProps = Record<'currentAccount' | 'children', React.ReactNode>;
-export function HomeLayout({ children }: HomeLayoutProps) {
- return (
-
-
-
- {children}
-
-
- );
-}
diff --git a/src/app/pages/home/components/send-button.tsx b/src/app/pages/home/components/send-button.tsx
index 76fc5aa68d0..b3a9916735b 100644
--- a/src/app/pages/home/components/send-button.tsx
+++ b/src/app/pages/home/components/send-button.tsx
@@ -13,10 +13,9 @@ import {
useTransferableStacksFungibleTokenAssetBalances,
} from '@app/query/stacks/balance/stacks-ft-balances.hooks';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { ActionButton } from '@app/ui/components/account/action-button';
import { SendIcon } from '@app/ui/icons';
-import { ActionButton } from './action-button';
-
function SendButtonSuspense() {
const navigate = useNavigate();
const { whenWallet } = useWalletType();
@@ -34,10 +33,10 @@ function SendButtonSuspense() {
whenWallet({
ledger: () =>
whenPageMode({
- full: () => navigate(RouteUrls.SendCryptoAsset, { state: { hasHeaderTitle: true } }),
+ full: () => navigate(RouteUrls.SendCryptoAsset),
popup: () => openIndexPageInNewTab(RouteUrls.SendCryptoAsset),
})(),
- software: () => navigate(RouteUrls.SendCryptoAsset, { state: { hasHeaderTitle: true } }),
+ software: () => navigate(RouteUrls.SendCryptoAsset),
})()
}
disabled={isDisabled}
diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx
index d6187512d63..2c19573e619 100644
--- a/src/app/pages/home/home.tsx
+++ b/src/app/pages/home/home.tsx
@@ -1,45 +1,64 @@
+import { useState } from 'react';
import { Route, useNavigate } from 'react-router-dom';
import { RouteUrls } from '@shared/route-urls';
+import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
+import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance';
import { useOnMount } from '@app/common/hooks/use-on-mount';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
import { ActivityList } from '@app/features/activity-list/activity-list';
import { AssetsList } from '@app/features/asset-list/asset-list';
+import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog';
import { FeedbackButton } from '@app/features/feedback-button/feedback-button';
-import { InAppMessages } from '@app/features/hiro-messages/in-app-messages';
import { homePageModalRoutes } from '@app/routes/app-routes';
import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper';
+import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
+import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { AccountCard } from '@app/ui/components/account/account.card';
+import { HomeLayout } from '@app/ui/pages/home.layout';
-import { CurrentAccount } from './components/account-area';
+import { AccountActions } from './components/account-actions';
import { HomeTabs } from './components/home-tabs';
-import { HomeLayout } from './components/home.layout';
export function Home() {
+ const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false);
const { decodedAuthRequest } = useOnboardingState();
const navigate = useNavigate();
+ const name = useCurrentAccountDisplayName();
- useRouteHeader(
- <>
-
-
- >
- );
+ const account = useCurrentStacksAccount();
+ const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero();
+ const totalBalance = useTotalBalance({ btcAddress, stxAddress: account?.address || '' });
useOnMount(() => {
if (decodedAuthRequest) navigate(RouteUrls.ChooseAccount);
});
return (
- }>
+ setIsShowingSwitchAccount(false)}
+ />
+ }
+ toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)}
+ >
+
+
+ }
+ >
} />
- }>
+ }>
{homePageModalRoutes}
{homePageModalRoutes}
diff --git a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx
index ccb2bc099aa..0be6e412648 100644
--- a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx
+++ b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx
@@ -1,10 +1,10 @@
-import { Dialog } from '@radix-ui/themes';
import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
-import { css } from 'leather-styles/css';
-import { Box, Flex, HStack, Stack, styled } from 'leather-styles/jsx';
+import { Box, Flex, Stack, styled } from 'leather-styles/jsx';
import { Button } from '@app/ui/components/button/button';
-import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Footer } from '@app/ui/components/containers/footers/footer';
+import { CheckmarkIcon } from '@app/ui/icons/';
import { LogomarkIcon } from '@app/ui/icons/logomark-icon';
interface ReasonToAllowDiagnosticsProps {
@@ -25,51 +25,53 @@ interface AllowDiagnosticsLayoutProps {
onUserAllowDiagnostics(): void;
onUserDenyDiagnostics(): void;
}
-export function AllowDiagnosticsLayout(props: AllowDiagnosticsLayoutProps) {
- const { onUserAllowDiagnostics, onUserDenyDiagnostics } = props;
+export function AllowDiagnosticsLayout({
+ onUserAllowDiagnostics,
+ onUserDenyDiagnostics,
+}: AllowDiagnosticsLayoutProps) {
return (
-
-
-
-
- Help us improve
-
-
+ null}
+ isShowing
+ footer={
+
+
+ onUserDenyDiagnostics()}
+ data-testid={OnboardingSelectors.DenyAnalyticsBtn}
+ >
+ Deny
+
+
+ Allow
+
+
+
+ }
+ >
+
+
+
+
+ Help us improve
+
Leather would like to gather deidentified service usage data to help improve the
experience of the wallet.
-
+
-
-
- onUserDenyDiagnostics()}
- data-testid={OnboardingSelectors.DenyAnalyticsBtn}
- >
- Deny
-
-
- Allow
-
-
-
-
+
+
);
}
diff --git a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx
index a7c44eab07f..4d1dd6e5263 100644
--- a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx
+++ b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx
@@ -5,8 +5,6 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { RouteUrls } from '@shared/route-urls';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
import { settingsActions } from '@app/store/settings/settings.actions';
import { AllowDiagnosticsLayout } from './allow-diagnostics-layout';
@@ -19,8 +17,6 @@ export function AllowDiagnosticsModal() {
useEffect(() => void analytics.page('view', `${pathname}`), [analytics, pathname]);
- useRouteHeader();
-
const setDiagnosticsPermissionsAndGoToOnboarding = useCallback(
(areDiagnosticsAllowed: boolean) => {
dispatch(settingsActions.setHasAllowedAnalytics(areDiagnosticsAllowed));
diff --git a/src/app/pages/onboarding/back-up-secret-key/back-up-secret-key.tsx b/src/app/pages/onboarding/back-up-secret-key/back-up-secret-key.tsx
index 210ab4f6ab0..8721ef746e3 100644
--- a/src/app/pages/onboarding/back-up-secret-key/back-up-secret-key.tsx
+++ b/src/app/pages/onboarding/back-up-secret-key/back-up-secret-key.tsx
@@ -1,22 +1,19 @@
import { memo, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
+import { HStack, Stack, styled } from 'leather-styles/jsx';
+
import { RouteUrls } from '@shared/route-urls';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
-import { TwoColumnLayout } from '@app/components/secret-key/two-column.layout';
-import { SecretKeyDisplayer } from '@app/features/secret-key-displayer/secret-key-displayer';
+import { SecretKey } from '@app/features/secret-key-displayer/secret-key-displayer';
import { useDefaultWalletSecretKey } from '@app/store/in-memory-key/in-memory-key.selectors';
-
-import { BackUpSecretKeyContent } from './components/back-up-secret-key.content';
+import { EyeSlashIcon, KeyIcon, LockIcon } from '@app/ui/icons/';
+import { TwoColumnLayout } from '@app/ui/pages/two-column.layout';
export const BackUpSecretKeyPage = memo(() => {
const secretKey = useDefaultWalletSecretKey();
const navigate = useNavigate();
- useRouteHeader();
-
useEffect(() => {
if (!secretKey) navigate(RouteUrls.Onboarding);
}, [navigate, secretKey]);
@@ -25,8 +22,37 @@ export const BackUpSecretKeyPage = memo(() => {
return (
}
- rightColumn={ }
- />
+ title={<>Back up your Secret Key>}
+ content={
+ <>
+ You'll need it to access your wallet on a new device, or this one if you lose your
+ password — so back it up somewhere safe!
+ >
+ }
+ action={
+
+
+
+
+ Your Secret Key gives access to your wallet
+
+
+
+
+
+ Never share your Secret Key with anyone
+
+
+
+
+
+ Store it somewhere 100% private and secure
+
+
+
+ }
+ >
+
+
);
});
diff --git a/src/app/pages/onboarding/back-up-secret-key/components/back-up-secret-key.content.tsx b/src/app/pages/onboarding/back-up-secret-key/components/back-up-secret-key.content.tsx
deleted file mode 100644
index 050fd314f75..00000000000
--- a/src/app/pages/onboarding/back-up-secret-key/components/back-up-secret-key.content.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { HStack, Stack, styled } from 'leather-styles/jsx';
-
-import { KeyIcon } from '@app/ui/icons';
-import { EyeSlashIcon } from '@app/ui/icons/eye-slash-icon';
-import { LockIcon } from '@app/ui/icons/lock-icon';
-
-export function BackUpSecretKeyContent(): React.JSX.Element {
- return (
- <>
-
- Back up your Secret Key
-
-
- Here's your Secret Key: 24 words that give you access to your new wallet.
-
-
- You'll need it to access your wallet on a new device, or this one if you lose your password
- — so back it up somewhere safe!
-
-
-
-
-
- Your Secret Key gives access to your wallet
-
-
-
- Never share your Secret Key with anyone
-
-
-
- Store it somewhere 100% private and secure
-
-
- >
- );
-}
diff --git a/src/app/pages/onboarding/set-password/components/password-bars.tsx b/src/app/pages/onboarding/set-password/components/password-bars.tsx
index afa5cc44e98..1aabe5f3610 100644
--- a/src/app/pages/onboarding/set-password/components/password-bars.tsx
+++ b/src/app/pages/onboarding/set-password/components/password-bars.tsx
@@ -6,21 +6,19 @@ interface PasswordStrengthBarsProps {
export function PasswordStrengthBars({ bars }: PasswordStrengthBarsProps) {
return (
- {bars.map((bar: string, index: number) => {
- return (
-
- );
- })}
+ {bars.map((bar: string, index: number) => (
+
+ ))}
);
}
diff --git a/src/app/pages/onboarding/set-password/set-password.tsx b/src/app/pages/onboarding/set-password/set-password.tsx
index b581478f9b9..dcc6e3efc09 100644
--- a/src/app/pages/onboarding/set-password/set-password.tsx
+++ b/src/app/pages/onboarding/set-password/set-password.tsx
@@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom';
import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
import { Form, Formik } from 'formik';
-import { styled } from 'leather-styles/jsx';
import { debounce } from 'ts-debounce';
import * as yup from 'yup';
@@ -14,16 +13,14 @@ import { useFinishAuthRequest } from '@app/common/authentication/use-finish-auth
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
import { useKeyActions } from '@app/common/hooks/use-key-actions';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import {
blankPasswordValidation,
validatePassword,
} from '@app/common/validation/validate-password';
-import { Header } from '@app/components/header';
-import { TwoColumnLayout } from '@app/components/secret-key/two-column.layout';
import { OnboardingGate } from '@app/routes/onboarding-gate';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { Button } from '@app/ui/components/button/button';
+import { TwoColumnLayout } from '@app/ui/pages/two-column.layout';
import { PasswordField } from './components/password-field';
@@ -53,8 +50,6 @@ function SetPasswordPage() {
const { decodedAuthRequest } = useOnboardingState();
const analytics = useAnalytics();
- useRouteHeader( navigate(-1)} />);
-
useEffect(() => {
void analytics.page('view', '/set-password');
}, [analytics]);
@@ -125,48 +120,33 @@ function SetPasswordPage() {
{({ dirty, isSubmitting, isValid }) => (
)}
diff --git a/src/app/pages/onboarding/sign-in/components/sign-in.content.tsx b/src/app/pages/onboarding/sign-in/components/sign-in.content.tsx
deleted file mode 100644
index 497c0bd6290..00000000000
--- a/src/app/pages/onboarding/sign-in/components/sign-in.content.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { styled } from 'leather-styles/jsx';
-
-import { Link } from '@app/ui/components/link/link';
-
-export function SignInContent({
- onClick,
- twentyFourWordMode,
-}: {
- onClick(): void;
- twentyFourWordMode: boolean;
-}): React.JSX.Element {
- return (
- <>
-
- Sign in with your
- Secret Key
-
-
- Speed things up by pasting your entire Secret Key in one go.
-
-
- {twentyFourWordMode ? 'Have a 12-word Secret Key?' : 'Use 24 word Secret Key'}
-
- >
- );
-}
diff --git a/src/app/pages/onboarding/sign-in/mnemonic-form.tsx b/src/app/pages/onboarding/sign-in/mnemonic-form.tsx
index e0c2f0b1060..2a9e327e497 100644
--- a/src/app/pages/onboarding/sign-in/mnemonic-form.tsx
+++ b/src/app/pages/onboarding/sign-in/mnemonic-form.tsx
@@ -1,22 +1,21 @@
import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
import { Form, Formik } from 'formik';
-import { Flex, styled } from 'leather-styles/jsx';
+import { Stack } from 'leather-styles/jsx';
import { isEmpty } from '@shared/utils';
import { createNullArrayOfLength } from '@app/common/utils';
import { ErrorLabel } from '@app/components/error-label';
-import { SecretKeyGrid } from '@app/components/secret-key/secret-key-grid';
import { useSignIn } from '@app/pages/onboarding/sign-in/hooks/use-sign-in';
import { Button } from '@app/ui/components/button/button';
-
-import { MnemonicWordInput } from '../../../components/secret-key/mnemonic-key/mnemonic-word-input';
+import { MnemonicWordInput } from '@app/ui/components/secret-key/mnemonic-key/mnemonic-word-input';
import {
getMnemonicErrorFields,
getMnemonicErrorMessage,
hasMnemonicFormValues,
-} from '../../../components/secret-key/mnemonic-key/utils/error-handling';
-import { validationSchema } from '../../../components/secret-key/mnemonic-key/utils/validation';
+} from '@app/ui/components/secret-key/mnemonic-key/utils/error-handling';
+import { validationSchema } from '@app/ui/components/secret-key/mnemonic-key/utils/validation';
+import { SecretKeyGrid } from '@app/ui/components/secret-key/secret-key-grid';
interface MnemonicFormProps {
mnemonic: (string | null)[];
@@ -69,24 +68,21 @@ export function MnemonicForm({ mnemonic, setMnemonic, twentyFourWordMode }: Mnem
return (
);
}}
diff --git a/src/app/pages/onboarding/sign-in/sign-in.tsx b/src/app/pages/onboarding/sign-in/sign-in.tsx
index faad25e2dcb..45083dfd0e6 100644
--- a/src/app/pages/onboarding/sign-in/sign-in.tsx
+++ b/src/app/pages/onboarding/sign-in/sign-in.tsx
@@ -1,24 +1,14 @@
import { useEffect, useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { RouteUrls } from '@shared/route-urls';
-
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { createNullArrayOfLength } from '@app/common/utils';
-import { Header } from '@app/components/header';
-import { TwoColumnLayout } from '@app/components/secret-key/two-column.layout';
import { MnemonicForm } from '@app/pages/onboarding/sign-in/mnemonic-form';
-
-import { SignInContent } from './components/sign-in.content';
+import { Link } from '@app/ui/components/link/link';
+import { TwoColumnLayout } from '@app/ui/pages/two-column.layout';
export function SignIn() {
- const navigate = useNavigate();
-
const [twentyFourWordMode, setTwentyFourWordMode] = useState(true);
const [mnemonic, setMnemonic] = useState<(string | null)[]>([]);
- useRouteHeader( navigate(RouteUrls.Onboarding)} hideActions />);
-
useEffect(() => {
const emptyMnemonicArray = twentyFourWordMode
? createNullArrayOfLength(24)
@@ -27,22 +17,29 @@ export function SignIn() {
}, [twentyFourWordMode]);
return (
- <>
- setTwentyFourWordMode(!twentyFourWordMode)}
- twentyFourWordMode={twentyFourWordMode}
- />
- }
- rightColumn={
-
- }
+
+ Sign in with your Secret Key
+ >
+ }
+ content={<>Speed things up by pasting your entire Secret Key in one go.>}
+ action={
+ setTwentyFourWordMode(!twentyFourWordMode)}
+ textStyle="label.03"
+ width="fit-content"
+ variant="text"
+ >
+ {twentyFourWordMode ? 'Have a 12-word Secret Key?' : 'Use 24 word Secret Key'}
+
+ }
+ >
+
- >
+
);
}
diff --git a/src/app/pages/onboarding/welcome/welcome.layout.tsx b/src/app/pages/onboarding/welcome/welcome.layout.tsx
deleted file mode 100644
index 64cee800550..00000000000
--- a/src/app/pages/onboarding/welcome/welcome.layout.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
-import { Box, Flex, styled } from 'leather-styles/jsx';
-
-import { useViewportMinWidth } from '@app/common/hooks/use-media-query';
-import { Button } from '@app/ui/components/button/button';
-import { Link } from '@app/ui/components/link/link';
-import { LettermarkIcon } from '@app/ui/icons/lettermark-icon';
-import { LogomarkIcon } from '@app/ui/icons/logomark-icon';
-
-interface WelcomeLayoutProps {
- tagline: React.ReactNode;
- subheader: React.ReactNode;
- isGeneratingWallet: boolean;
- onSelectConnectLedger(): void;
- onStartOnboarding(): void;
- onRestoreWallet(): void;
-}
-export function WelcomeLayout({
- tagline,
- subheader,
- isGeneratingWallet,
- onStartOnboarding,
- onSelectConnectLedger,
- onRestoreWallet,
-}: WelcomeLayoutProps): React.JSX.Element {
- const isAtleastBreakpointMd = useViewportMinWidth('md');
-
- return (
-
-
-
-
-
- {tagline}
-
-
- {subheader}
-
-
-
-
-
- Create new wallet
-
-
-
- Use existing key
-
-
- Use existing key
-
-
- Use Ledger
-
-
- Use Ledger
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/app/pages/onboarding/welcome/welcome.tsx b/src/app/pages/onboarding/welcome/welcome.tsx
index b513e63bcaf..ae3a1d54166 100644
--- a/src/app/pages/onboarding/welcome/welcome.tsx
+++ b/src/app/pages/onboarding/welcome/welcome.tsx
@@ -7,12 +7,10 @@ import { closeWindow } from '@shared/utils';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
import { useKeyActions } from '@app/common/hooks/use-key-actions';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { doesBrowserSupportWebUsbApi, isPopupMode, whenPageMode } from '@app/common/utils';
import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
import { useHasUserRespondedToAnalyticsConsent } from '@app/store/settings/settings.selectors';
-
-import { WelcomeLayout } from './welcome.layout';
+import { WelcomeLayout } from '@app/ui/pages/welcome.layout';
export function WelcomePage() {
const hasResponded = useHasUserRespondedToAnalyticsConsent();
@@ -23,7 +21,6 @@ export function WelcomePage() {
const [isGeneratingWallet, setIsGeneratingWallet] = useState(false);
- useRouteHeader(<>>);
const startOnboarding = useCallback(async () => {
if (isPopupMode()) {
openIndexPageInNewTab(RouteUrls.Onboarding);
@@ -79,8 +76,6 @@ export function WelcomePage() {
return (
<>
startOnboarding()}
diff --git a/src/app/pages/receive/components/receive-collectibles.tsx b/src/app/pages/receive/components/receive-collectibles.tsx
new file mode 100644
index 00000000000..fd0999e859f
--- /dev/null
+++ b/src/app/pages/receive/components/receive-collectibles.tsx
@@ -0,0 +1,55 @@
+import { HomePageSelectors } from '@tests/selectors/home.selectors';
+import { css } from 'leather-styles/css';
+import { Stack } from 'leather-styles/jsx';
+
+import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
+import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
+import { StampsIcon } from '@app/ui/components/avatar-icon//stamps-icon';
+import { OrdinalIcon } from '@app/ui/components/avatar-icon/ordinal-icon';
+
+import { receiveTabStyle } from '../receive-dialog';
+import { ReceiveItem } from './receive-item';
+
+interface ReceiveCollectiblesProps {
+ btcAddressTaproot: string;
+ btcAddressNativeSegwit: string;
+ stxAddress: string;
+ onClickQrOrdinal(): void;
+ onClickQrStacksNft(): void;
+ onClickQrStamp(): void;
+}
+export function ReceiveCollectibles({
+ btcAddressTaproot,
+ btcAddressNativeSegwit,
+ stxAddress,
+ onClickQrOrdinal,
+ onClickQrStacksNft,
+ onClickQrStamp,
+}: ReceiveCollectiblesProps) {
+ return (
+
+ }
+ dataTestId={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn}
+ onCopyAddress={() => copyToClipboard(btcAddressTaproot)}
+ onClickQrCode={onClickQrOrdinal}
+ title="Ordinal inscription"
+ />
+ }
+ onClickQrCode={onClickQrStamp}
+ onCopyAddress={() => copyToClipboard(btcAddressNativeSegwit)}
+ title="Bitcoin Stamp"
+ />
+ }
+ onCopyAddress={() => copyToClipboard(stxAddress)}
+ onClickQrCode={onClickQrStacksNft}
+ title="Stacks NFT"
+ />
+
+ );
+}
diff --git a/src/app/pages/receive/components/receive-items.tsx b/src/app/pages/receive/components/receive-items.tsx
deleted file mode 100644
index 7a42aa5d28b..00000000000
--- a/src/app/pages/receive/components/receive-items.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Divider, Stack, styled } from 'leather-styles/jsx';
-
-interface ReceiveItemListProps {
- children: React.ReactNode;
- title?: string;
-}
-export function ReceiveItemList({ children, title }: ReceiveItemListProps) {
- return (
- <>
- {title && (
-
- {title}
-
- )}
-
-
- {children}
-
- >
- );
-}
diff --git a/src/app/pages/receive/components/receive-tokens.layout.tsx b/src/app/pages/receive/components/receive-tokens.layout.tsx
index 3fc721c3bfc..86c7172b2d9 100644
--- a/src/app/pages/receive/components/receive-tokens.layout.tsx
+++ b/src/app/pages/receive/components/receive-tokens.layout.tsx
@@ -5,9 +5,11 @@ import { Box, Flex, styled } from 'leather-styles/jsx';
import { useLocationState } from '@app/common/hooks/use-location-state';
import { AddressDisplayer } from '@app/components/address-displayer/address-displayer';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
import { Button } from '@app/ui/components/button/button';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Footer } from '@app/ui/components/containers/footers/footer';
+import { Header } from '@app/ui/components/containers/headers/header';
import { QrCode } from './address-qr-code';
@@ -26,7 +28,24 @@ export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) {
const backgroundLocation = useLocationState('backgroundLocation');
return (
- navigate(backgroundLocation ?? '..')}>
+ navigate(backgroundLocation ?? '..')}
+ />
+ }
+ isShowing
+ onClose={() => navigate(backgroundLocation ?? '..')}
+ footer={
+
+ onCopyAddressToClipboard(address)}>
+ Copy address
+
+
+ }
+ >
{warning && warning}
@@ -51,10 +70,7 @@ export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) {
- onCopyAddressToClipboard(address)}>
- Copy address
-
-
+
);
}
diff --git a/src/app/pages/receive/components/receive-tokens.tsx b/src/app/pages/receive/components/receive-tokens.tsx
new file mode 100644
index 00000000000..d64acf158c5
--- /dev/null
+++ b/src/app/pages/receive/components/receive-tokens.tsx
@@ -0,0 +1,44 @@
+import { HomePageSelectors } from '@tests/selectors/home.selectors';
+import { css } from 'leather-styles/css';
+import { Stack } from 'leather-styles/jsx';
+
+import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
+import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
+import { BtcIcon } from '@app/ui/components/avatar-icon/btc-icon';
+
+import { receiveTabStyle } from '../receive-dialog';
+import { ReceiveItem } from './receive-item';
+
+interface ReceiveTokensProps {
+ btcAddressNativeSegwit: string;
+ stxAddress: string;
+ onClickQrBtc(): void;
+ onClickQrStx(): void;
+}
+export function ReceiveTokens({
+ btcAddressNativeSegwit,
+ stxAddress,
+ onClickQrBtc,
+ onClickQrStx,
+}: ReceiveTokensProps) {
+ return (
+
+ }
+ dataTestId={HomePageSelectors.ReceiveBtcNativeSegwitQrCodeBtn}
+ onCopyAddress={() => copyToClipboard(btcAddressNativeSegwit)}
+ onClickQrCode={onClickQrBtc}
+ title="Bitcoin"
+ />
+ }
+ dataTestId={HomePageSelectors.ReceiveStxQrCodeBtn}
+ onCopyAddress={() => copyToClipboard(stxAddress)}
+ onClickQrCode={onClickQrStx}
+ title="Stacks"
+ />
+
+ );
+}
diff --git a/src/app/pages/receive/receive-btc.tsx b/src/app/pages/receive/receive-btc.tsx
index a91b73be5e7..c4f90075f41 100644
--- a/src/app/pages/receive/receive-btc.tsx
+++ b/src/app/pages/receive/receive-btc.tsx
@@ -1,10 +1,9 @@
-import toast from 'react-hot-toast';
import { useLocation } from 'react-router-dom';
import get from 'lodash.get';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
+import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { useNativeSegwitAccountIndexAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
@@ -26,18 +25,13 @@ export function ReceiveBtcModal({ type = 'btc' }: ReceiveBtcModalType) {
const activeAccountBtcAddress = useNativeSegwitAccountIndexAddressIndexZero(accountIndex);
const btcAddress = get(state, 'btcAddress', activeAccountBtcAddress);
- const { onCopy } = useClipboard(btcAddress);
-
- function copyToClipboard() {
- void analytics.track('copy_btc_address_to_clipboard');
- toast.success('Copied to clipboard!');
- onCopy();
- }
-
return (
{
+ void analytics.track('copy_btc_address_to_clipboard');
+ copyToClipboard(btcAddress);
+ }}
title={type === 'btc-stamp' ? 'BITCOIN STAMP' : 'BTC'}
/>
);
diff --git a/src/app/pages/receive/receive-dialog.tsx b/src/app/pages/receive/receive-dialog.tsx
new file mode 100644
index 00000000000..1ba14beaacc
--- /dev/null
+++ b/src/app/pages/receive/receive-dialog.tsx
@@ -0,0 +1,126 @@
+import { useLocation, useNavigate } from 'react-router-dom';
+
+import { HomePageSelectors } from '@tests/selectors/home.selectors';
+import { styled } from 'leather-styles/jsx';
+import get from 'lodash.get';
+
+import { RouteUrls } from '@shared/route-urls';
+
+import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
+import { useLocationState } from '@app/common/hooks/use-location-state';
+import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
+import { useZeroIndexTaprootAddress } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks';
+import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
+import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
+import { Tabs } from '@app/ui/components/tabs/tabs';
+
+import { ReceiveCollectibles } from './components/receive-collectibles';
+import { ReceiveTokens } from './components/receive-tokens';
+
+type ReceiveDialog = 'full' | 'collectible';
+
+// TODO ask design ideally all tabs should match but choose-fee has a different variation
+export const receiveTabStyle = {
+ mt: 'space.03',
+ paddingX: 'space.03',
+ pb: 'space.05',
+};
+
+interface ReceiveDialogProps {
+ type?: 'full' | 'collectible';
+}
+
+export function ReceiveDialog({ type = 'full' }: ReceiveDialogProps) {
+ useBackgroundLocationRedirect();
+ const analytics = useAnalytics();
+ const backgroundLocation = useLocationState('backgroundLocation');
+ const navigate = useNavigate();
+ const location = useLocation();
+ const btcAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero();
+ const stxAddress = useCurrentAccountStxAddressState();
+ const accountIndex = get(location.state, 'accountIndex', undefined);
+ const btcAddressTaproot = useZeroIndexTaprootAddress(accountIndex);
+
+ const title = type === 'full' ? 'Choose asset to receive' : 'Receive collectible';
+
+ function Collectibles() {
+ return (
+ {
+ void analytics.track('select_inscription_to_add_new_collectible');
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveCollectibleOrdinal}`, {
+ state: {
+ btcAddressTaproot,
+ backgroundLocation,
+ },
+ });
+ }}
+ onClickQrStamp={() =>
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtcStamp}`, {
+ state: { backgroundLocation },
+ })
+ }
+ onClickQrStacksNft={() =>
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
+ state: { backgroundLocation },
+ })
+ }
+ />
+ );
+ }
+
+ return (
+ navigate(backgroundLocation ?? '..')}
+ title={{title} }
+ />
+ }
+ onClose={() => navigate(backgroundLocation ?? '..')}
+ isShowing
+ >
+ {type === 'collectible' && }
+ {type === 'full' && (
+
+
+
+ Tokens
+
+
+ Collectibles
+
+
+
+
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtc}`, {
+ state: { backgroundLocation },
+ })
+ }
+ onClickQrStx={() =>
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
+ state: { backgroundLocation, btcAddressTaproot },
+ })
+ }
+ />
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/src/app/pages/receive/receive-modal.tsx b/src/app/pages/receive/receive-modal.tsx
deleted file mode 100644
index b39ca8b0e75..00000000000
--- a/src/app/pages/receive/receive-modal.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import toast from 'react-hot-toast';
-import { useLocation, useNavigate } from 'react-router-dom';
-
-import { HomePageSelectors } from '@tests/selectors/home.selectors';
-import { Box, styled } from 'leather-styles/jsx';
-import get from 'lodash.get';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
-import { useLocationState } from '@app/common/hooks/use-location-state';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
-import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
-import { useZeroIndexTaprootAddress } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks';
-import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
-import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
-import { BtcAvatarIcon } from '@app/ui/components/avatar/btc-avatar-icon';
-import { OrdinalAvatarIcon } from '@app/ui/components/avatar/ordinal-avatar-icon';
-import { StampsAvatarIcon } from '@app/ui/components/avatar/stamps-avatar-icon';
-import { StxAvatarIcon } from '@app/ui/components/avatar/stx-avatar-icon';
-
-import { ReceiveItem } from './components/receive-item';
-import { ReceiveItemList } from './components/receive-items';
-
-type ReceiveModal = 'full' | 'collectible';
-
-interface ReceiveModalProps {
- type?: 'full' | 'collectible';
-}
-
-export function ReceiveModal({ type = 'full' }: ReceiveModalProps) {
- useBackgroundLocationRedirect();
- const analytics = useAnalytics();
- const backgroundLocation = useLocationState('backgroundLocation');
- const navigate = useNavigate();
- const location = useLocation();
- const btcAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero();
- const stxAddress = useCurrentAccountStxAddressState();
- const accountIndex = get(location.state, 'accountIndex', undefined);
- const btcAddressTaproot = useZeroIndexTaprootAddress(accountIndex);
-
- const { onCopy: onCopyBtc } = useClipboard(btcAddressNativeSegwit);
- const { onCopy: onCopyStx } = useClipboard(stxAddress);
- const { onCopy: onCopyOrdinal } = useClipboard(btcAddressTaproot);
-
- function copyToClipboard(copyHandler: () => void, tracker = 'copy_address_to_clipboard') {
- void analytics.track(tracker);
- toast.success('Copied to clipboard!');
- copyHandler();
- }
-
- const title =
- type === 'full' ? (
- <>
- Choose asset
-
- to receive
- >
- ) : (
- <>
- Receive
-
- collectible
- >
- );
-
- return (
- <>
- navigate(backgroundLocation ?? '..')}>
-
-
- {title}
-
- {type === 'full' && (
-
- }
- dataTestId={HomePageSelectors.ReceiveBtcNativeSegwitQrCodeBtn}
- onCopyAddress={() => copyToClipboard(onCopyBtc)}
- onClickQrCode={() =>
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtc}`, {
- state: { backgroundLocation },
- })
- }
- title="Bitcoin"
- />
- }
- dataTestId={HomePageSelectors.ReceiveStxQrCodeBtn}
- onCopyAddress={() => copyToClipboard(onCopyStx)}
- onClickQrCode={() =>
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
- state: { backgroundLocation, btcAddressTaproot },
- })
- }
- title="Stacks"
- />
-
- )}
-
- }
- dataTestId={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn}
- onCopyAddress={() =>
- copyToClipboard(onCopyOrdinal, 'select_stamp_to_add_new_collectible')
- }
- onClickQrCode={() => {
- void analytics.track('select_inscription_to_add_new_collectible');
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveCollectibleOrdinal}`, {
- state: {
- btcAddressTaproot,
- backgroundLocation,
- },
- });
- }}
- title="Ordinal inscription"
- />
- }
- onClickQrCode={() =>
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtcStamp}`, {
- state: { backgroundLocation },
- })
- }
- onCopyAddress={() =>
- copyToClipboard(onCopyBtc, 'select_stamp_to_add_new_collectible')
- }
- title="Bitcoin Stamp"
- />
- }
- onCopyAddress={() => copyToClipboard(onCopyStx, 'select_nft_to_add_new_collectible')}
- onClickQrCode={() =>
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
- state: { backgroundLocation },
- })
- }
- title="Stacks NFT"
- />
-
-
-
- >
- );
-}
diff --git a/src/app/pages/receive/receive-ordinal.tsx b/src/app/pages/receive/receive-ordinal.tsx
index a061131caca..b61036999b1 100644
--- a/src/app/pages/receive/receive-ordinal.tsx
+++ b/src/app/pages/receive/receive-ordinal.tsx
@@ -1,8 +1,7 @@
-import toast from 'react-hot-toast';
import { useLocation } from 'react-router-dom';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
+import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
import { ReceiveBtcModalWarning } from './components/receive-btc-warning';
@@ -12,18 +11,15 @@ export function ReceiveOrdinalModal() {
useBackgroundLocationRedirect();
const analytics = useAnalytics();
const { state } = useLocation();
- const { onCopy } = useClipboard(state.btcAddressTaproot);
- function copyToClipboard() {
- void analytics.track('copy_address_to_add_new_inscription');
- toast.success('Copied to clipboard!');
- onCopy();
- }
// #4028 FIXME - this doesn't open in new tab as it loses btcAddressTaproot amd crashes btcStamp and Stx are OK?
return (
{
+ void analytics.track('copy_address_to_add_new_inscription');
+ copyToClipboard(state.btcAddressTaproot);
+ }}
title="ORD. INSCRIPTION"
warning={ }
/>
diff --git a/src/app/pages/receive/receive-stx.tsx b/src/app/pages/receive/receive-stx.tsx
index c785a0e7de1..94c4a16d0c1 100644
--- a/src/app/pages/receive/receive-stx.tsx
+++ b/src/app/pages/receive/receive-stx.tsx
@@ -1,8 +1,6 @@
-import toast from 'react-hot-toast';
-
import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
+import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
@@ -12,22 +10,18 @@ export function ReceiveStxModal() {
useBackgroundLocationRedirect();
const currentAccount = useCurrentStacksAccount();
const analytics = useAnalytics();
- const { onCopy } = useClipboard(currentAccount?.address ?? '');
const accountName = useCurrentAccountDisplayName();
- function copyToClipboard() {
- void analytics.track('copy_stx_address_to_clipboard');
- toast.success('Copied to clipboard');
- onCopy();
- }
-
if (!currentAccount) return null;
return (
{
+ void analytics.track('copy_stx_address_to_clipboard');
+ copyToClipboard(currentAccount.address);
+ }}
title="STX"
/>
);
diff --git a/src/app/pages/rpc-send-transfer/rpc-send-transfer-confirmation.tsx b/src/app/pages/rpc-send-transfer/rpc-send-transfer-confirmation.tsx
index 03231b49b59..a144c96ce8a 100644
--- a/src/app/pages/rpc-send-transfer/rpc-send-transfer-confirmation.tsx
+++ b/src/app/pages/rpc-send-transfer/rpc-send-transfer-confirmation.tsx
@@ -61,7 +61,6 @@ export function RpcSendTransferConfirmation() {
function formBtcTxSummaryState(txId: string) {
return {
- hasHeaderTitle: true,
txLink: {
blockchain: 'bitcoin',
txid: txId || '',
diff --git a/src/app/pages/rpc-send-transfer/rpc-send-transfer-container.tsx b/src/app/pages/rpc-send-transfer/rpc-send-transfer-container.tsx
index a2340e4e06c..d7ff29bf6dc 100644
--- a/src/app/pages/rpc-send-transfer/rpc-send-transfer-container.tsx
+++ b/src/app/pages/rpc-send-transfer/rpc-send-transfer-container.tsx
@@ -4,9 +4,6 @@ import { Outlet, useOutletContext } from 'react-router-dom';
import { BtcFeeType } from '@shared/models/fees/bitcoin-fees.model';
import { closeWindow } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { PopupHeader } from '@app/features/current-account/popup-header';
-
import { RpcSendTransferContainerLayout } from './components/rpc-send-transfer-container.layout';
import { useRpcSendTransfer } from './use-rpc-send-transfer';
@@ -23,8 +20,6 @@ export function RpcSendTransferContainer() {
const [selectedFeeType, setSelectedFeeType] = useState(null);
const { origin } = useRpcSendTransfer();
- useRouteHeader( );
-
if (origin === null) {
closeWindow();
throw new Error('Origin is null');
diff --git a/src/app/pages/rpc-sign-bip322-message/rpc-sign-bip322-message.tsx b/src/app/pages/rpc-sign-bip322-message/rpc-sign-bip322-message.tsx
index 192f19d16d1..2b5cffebb77 100644
--- a/src/app/pages/rpc-sign-bip322-message/rpc-sign-bip322-message.tsx
+++ b/src/app/pages/rpc-sign-bip322-message/rpc-sign-bip322-message.tsx
@@ -2,10 +2,8 @@ import { Outlet } from 'react-router-dom';
import { closeWindow } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { Disclaimer } from '@app/components/disclaimer';
import { NoFeesWarningRow } from '@app/components/no-fees-warning-row';
-import { PopupHeader } from '@app/features/current-account/popup-header';
import { MessagePreviewBox } from '@app/features/message-signer/message-preview-box';
import { MessageSigningRequestLayout } from '@app/features/message-signer/message-signing-request.layout';
import { AccountGate } from '@app/routes/account-gate';
@@ -27,8 +25,6 @@ export function RpcSignBip322MessageRoute() {
}
function RpcSignBip322Message() {
- useRouteHeader( );
-
const {
origin,
message,
diff --git a/src/app/pages/rpc-sign-psbt/use-rpc-sign-psbt.tsx b/src/app/pages/rpc-sign-psbt/use-rpc-sign-psbt.tsx
index a1a00da17ae..0ed40f404d2 100644
--- a/src/app/pages/rpc-sign-psbt/use-rpc-sign-psbt.tsx
+++ b/src/app/pages/rpc-sign-psbt/use-rpc-sign-psbt.tsx
@@ -61,7 +61,6 @@ export function useRpcSignPsbt() {
const psbtTxSummaryState = {
fee: formatMoneyPadded(fee),
- hasHeaderTitle: true,
sendingValue: formatMoney(transferTotalAsMoney),
totalSpend: formatMoney(sumMoney([transferTotalAsMoney, fee])),
txFiatValue: i18nFormatCurrency(calculateBitcoinFiatValue(transferTotalAsMoney)),
diff --git a/src/app/pages/select-network/components/add-network-button.tsx b/src/app/pages/select-network/components/add-network-button.tsx
deleted file mode 100644
index f26b43de8ed..00000000000
--- a/src/app/pages/select-network/components/add-network-button.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Flex } from 'leather-styles/jsx';
-
-import { Button } from '@app/ui/components/button/button';
-
-interface AddNetworkButtonProps {
- onAddNetwork(): void;
-}
-export function AddNetworkButton({ onAddNetwork }: AddNetworkButtonProps) {
- return (
-
-
- Add a network
-
-
- );
-}
diff --git a/src/app/pages/select-network/components/network-list.layout.tsx b/src/app/pages/select-network/components/network-list.layout.tsx
deleted file mode 100644
index 302dedf8429..00000000000
--- a/src/app/pages/select-network/components/network-list.layout.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Flex, FlexProps } from 'leather-styles/jsx';
-
-export function NetworkListLayout({ children, ...props }: FlexProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/pages/select-network/components/network-status-indicator.tsx b/src/app/pages/select-network/components/network-status-indicator.tsx
deleted file mode 100644
index 5205ab80e70..00000000000
--- a/src/app/pages/select-network/components/network-status-indicator.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
-import { CloudOffIcon } from '@app/ui/icons/cloud-off-icon';
-
-interface NetworkStatusIndicatorProps {
- isActive: boolean;
- isOnline: boolean;
-}
-export function NetworkStatusIndicator({ isActive, isOnline }: NetworkStatusIndicatorProps) {
- return !isOnline ? : isActive ? : null;
-}
diff --git a/src/app/pages/select-network/select-network.tsx b/src/app/pages/select-network/select-network.tsx
deleted file mode 100644
index 270036a87a9..00000000000
--- a/src/app/pages/select-network/select-network.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { useNavigate } from 'react-router-dom';
-
-import { WalletDefaultNetworkConfigurationIds } from '@shared/constants';
-import { RouteUrls } from '@shared/route-urls';
-
-import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useLocationState } from '@app/common/hooks/use-location-state';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
-import { NetworkListLayout } from '@app/pages/select-network/components/network-list.layout';
-import { NetworkListItem } from '@app/pages/select-network/network-list-item';
-import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
-import { useCurrentNetworkState, useNetworksActions } from '@app/store/networks/networks.hooks';
-import { useNetworks } from '@app/store/networks/networks.selectors';
-
-import { AddNetworkButton } from './components/add-network-button';
-
-const defaultNetworkIds = Object.values(WalletDefaultNetworkConfigurationIds) as string[];
-
-export function SelectNetwork() {
- useBackgroundLocationRedirect();
- const navigate = useNavigate();
- const networks = useNetworks();
- const analytics = useAnalytics();
- const networksActions = useNetworksActions();
- const currentNetwork = useCurrentNetworkState();
- const backgroundLocation = useLocationState('backgroundLocation');
-
- function addNetwork() {
- void analytics.track('add_network');
- navigate(RouteUrls.AddNetwork);
- }
-
- function removeNetwork(id: string) {
- void analytics.track('remove_network');
- networksActions.removeNetwork(id);
- }
-
- function selectNetwork(id: string) {
- void analytics.track('change_network', { id });
- networksActions.changeNetwork(id);
- closeNetworkModal();
- }
-
- function closeNetworkModal() {
- navigate(backgroundLocation ?? '..');
- }
-
- return (
-
-
- {Object.keys(networks).map(id => (
- selectNetwork(id)}
- isCustom={!defaultNetworkIds.includes(id)}
- onRemoveNetwork={id => {
- if (id === currentNetwork.id) networksActions.changeNetwork('mainnet');
- removeNetwork(id);
- }}
- />
- ))}
-
-
-
- );
-}
diff --git a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx
index 5e8c25d976b..f96c964a2f7 100644
--- a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx
+++ b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx
@@ -1,17 +1,17 @@
import toast from 'react-hot-toast';
import { useNavigate } from 'react-router-dom';
+import { styled } from 'leather-styles/jsx';
+
import { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset-balance.model';
import { RouteUrls } from '@shared/route-urls';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useAllTransferableCryptoAssetBalances } from '@app/common/hooks/use-transferable-asset-balances.hooks';
import { useWalletType } from '@app/common/use-wallet-type';
-import { ChooseCryptoAssetLayout } from '@app/components/crypto-assets/choose-crypto-asset/choose-crypto-asset.layout';
import { CryptoAssetList } from '@app/components/crypto-assets/choose-crypto-asset/crypto-asset-list';
-import { ModalHeader } from '@app/components/modal-header';
import { useConfigBitcoinSendEnabled } from '@app/query/common/remote-config/remote-config.query';
import { useCheckLedgerBlockchainAvailable } from '@app/store/accounts/blockchain/utils';
+import { Card } from '@app/ui/layout/card/card';
export function ChooseCryptoAsset() {
const allTransferableCryptoAssetBalances = useAllTransferableCryptoAssetBalances();
@@ -22,8 +22,6 @@ export function ChooseCryptoAsset() {
const checkBlockchainAvailable = useCheckLedgerBlockchainAvailable();
- useRouteHeader( );
-
function navigateToSendForm(cryptoAssetBalance: AllTransferableCryptoAssetBalances) {
const { asset } = cryptoAssetBalance;
if (asset.symbol === 'BTC' && !isBitcoinSendEnabled) {
@@ -44,7 +42,13 @@ export function ChooseCryptoAsset() {
}
return (
-
+
+ choose asset to send
+
+ }
+ >
navigateToSendForm(cryptoAssetBalance)}
cryptoAssetBalances={allTransferableCryptoAssetBalances.filter(asset =>
@@ -54,6 +58,6 @@ export function ChooseCryptoAsset() {
})
)}
/>
-
+
);
}
diff --git a/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx b/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx
index c8a5f034a2d..3dbdc831ad9 100644
--- a/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx
+++ b/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx
@@ -6,7 +6,6 @@ import { HStack, styled } from 'leather-styles/jsx';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useBitcoinExplorerLink } from '@app/common/hooks/use-bitcoin-explorer-link';
import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { satToBtc } from '@app/common/money/unit-conversion';
import {
InfoCard,
@@ -14,7 +13,6 @@ import {
InfoCardBtn,
InfoCardFooter,
} from '@app/components/info-card/info-card';
-import { ModalHeader } from '@app/components/modal-header';
import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
@@ -38,8 +36,6 @@ export function LockBitcoinSummary() {
toast.success('ID copied!');
}
- useRouteHeader( );
-
return (
- navigate(-1)}>
+ }
+ isShowing
+ onGoBack={() => navigate(-1)}
+ onClose={() => navigate(-1)}
+ >
-
+
>
);
diff --git a/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx b/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx
index 59d3e4f0afb..f16d0708e30 100644
--- a/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx
+++ b/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx
@@ -5,12 +5,13 @@ import { Box, Flex } from 'leather-styles/jsx';
import { RouteUrls } from '@shared/route-urls';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { ErrorLabel } from '@app/components/error-label';
import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview';
import { InscriptionPreviewCard } from '@app/components/inscription-preview-card/inscription-preview-card';
import { OrdinalAvatarIcon } from '@app/ui/components/avatar/ordinal-avatar-icon';
import { Button } from '@app/ui/components/button/button';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { RecipientAddressTypeField } from '../send-crypto-asset-form/components/recipient-address-type-field';
import { CollectibleAsset } from './components/collectible-asset';
@@ -37,7 +38,12 @@ export function SendInscriptionForm() {
onSubmit={chooseTransactionFee}
>
);
diff --git a/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx b/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx
index c4a0d5ab348..66d9027a03e 100644
--- a/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx
+++ b/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx
@@ -8,13 +8,14 @@ import { RouteUrls } from '@shared/route-urls';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { InfoCard, InfoCardRow, InfoCardSeparator } from '@app/components/info-card/info-card';
import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useAppDispatch } from '@app/store';
import { inscriptionSent } from '@app/store/ordinals/ordinals.slice';
import { Button } from '@app/ui/components/button/button';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { InscriptionPreviewCard } from '../../../components/inscription-preview-card/inscription-preview-card';
import { useBitcoinBroadcastTransaction } from '../../../query/bitcoin/transaction/use-bitcoin-broadcast-transaction';
@@ -70,7 +71,12 @@ export function SendInscriptionReview() {
}
return (
- navigate(RouteUrls.Home)}>
+ }
+ isShowing
+ onGoBack={() => navigate(-1)}
+ onClose={() => navigate(RouteUrls.Home)}
+ >
}
@@ -91,6 +97,6 @@ export function SendInscriptionReview() {
Confirm and send transaction
-
+
);
}
diff --git a/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx b/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx
index 7a1b051e65b..91b059c631f 100644
--- a/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx
+++ b/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx
@@ -12,7 +12,6 @@ import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useBitcoinExplorerLink } from '@app/common/hooks/use-bitcoin-explorer-link';
import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import {
InfoCard,
InfoCardBtn,
@@ -20,6 +19,8 @@ import {
InfoCardSeparator,
} from '@app/components/info-card/info-card';
import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { CheckmarkIcon } from '@app/ui/icons/checkmark-icon';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
@@ -61,7 +62,11 @@ export function SendInscriptionSummary() {
}
return (
- navigate(RouteUrls.Home)}>
+ }
+ isShowing
+ onClose={() => navigate(RouteUrls.Home)}
+ >
}
@@ -84,6 +89,6 @@ export function SendInscriptionSummary() {
} label="Copy ID" />
-
+
);
}
diff --git a/src/app/pages/send/send-container.tsx b/src/app/pages/send/send-container.tsx
deleted file mode 100644
index fca5abb1b6b..00000000000
--- a/src/app/pages/send/send-container.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Outlet } from 'react-router-dom';
-
-import { Flex } from 'leather-styles/jsx';
-
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { whenPageMode } from '@app/common/utils';
-import { ModalHeader } from '@app/components/modal-header';
-
-export function SendContainer() {
- useRouteHeader( , true);
-
- return whenPageMode({
- full: (
-
-
-
- ),
- popup: (
-
-
-
- ),
- });
-}
diff --git a/src/app/pages/send/send-crypto-asset-form/components/form-footer.tsx b/src/app/pages/send/send-crypto-asset-form/components/form-footer.tsx
deleted file mode 100644
index 0333803e457..00000000000
--- a/src/app/pages/send/send-crypto-asset-form/components/form-footer.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Box, Flex } from 'leather-styles/jsx';
-
-import { Money } from '@shared/models/money.model';
-
-import { whenPageMode } from '@app/common/utils';
-import { AvailableBalance } from '@app/components/available-balance';
-import { PreviewButton } from '@app/components/preview-button';
-
-export function FormFooter(props: { balance: Money; balanceTooltipLabel?: string }) {
- const { balance, balanceTooltipLabel } = props;
-
- return (
-
-
-
-
-
-
- );
-}
diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/account-list-item.tsx
similarity index 95%
rename from src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx
rename to src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/account-list-item.tsx
index d59114ed9d0..9b532794329 100644
--- a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/account-list-item.tsx
@@ -7,11 +7,11 @@ import { BitcoinSendFormValues, StacksSendFormValues } from '@shared/models/form
import { useAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { AccountTotalBalance } from '@app/components/account-total-balance';
import { AcccountAddresses } from '@app/components/account/account-addresses';
-import { AccountAvatarItem } from '@app/components/account/account-avatar-item';
import { AccountListItemLayout } from '@app/components/account/account-list-item.layout';
import { AccountNameLayout } from '@app/components/account/account-name';
import { useNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
+import { AccountAvatarItem } from '@app/ui/components/account/account-avatar/account-avatar-item';
interface AccountListItemProps {
stacksAccount: StacksAccount;
diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/recipient-accounts-drawer.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx
similarity index 60%
rename from src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/recipient-accounts-drawer.tsx
rename to src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx
index d14745b071e..dfb7ffb0138 100644
--- a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/recipient-accounts-drawer.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx
@@ -2,15 +2,17 @@ import { memo, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { Virtuoso } from 'react-virtuoso';
+import { css } from 'leather-styles/css';
import { Box } from 'leather-styles/jsx';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
+import { Header } from '@app/ui/components/containers/headers/header';
import { AccountListItem } from './account-list-item';
-export const RecipientAccountsDrawer = memo(() => {
+export const RecipientAccountsDialog = memo(() => {
const stacksAccounts = useStacksAccounts();
const navigate = useNavigate();
@@ -20,25 +22,26 @@ export const RecipientAccountsDrawer = memo(() => {
const stacksAddressesNum = stacksAccounts.length;
if (stacksAddressesNum === 0 && btcAddressesNum === 0) return null;
-
return (
-
+ } isShowing onClose={onGoBack}>
+ {/* // TODO check Kyrans margin needed */}
(
-
-
-
+
)}
- style={{ paddingTop: '24px', height: '70vh' }}
totalCount={stacksAddressesNum || btcAddressesNum}
/>
-
+
);
});
diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/select-account-button.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/select-account-button.tsx
similarity index 100%
rename from src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/select-account-button.tsx
rename to src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/select-account-button.tsx
diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-type-dropdown/recipient-type-dropdown.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-type-dropdown/recipient-type-dropdown.tsx
index ee9ecdc1f36..1ee2a369dbe 100644
--- a/src/app/pages/send/send-crypto-asset-form/components/recipient-type-dropdown/recipient-type-dropdown.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/components/recipient-type-dropdown/recipient-type-dropdown.tsx
@@ -1,6 +1,6 @@
import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
-import { DropdownMenu } from '@app/ui/components/dowpdown-menu/dropdown-menu';
+import { DropdownMenu } from '@app/ui/components/dropdown-menu/dropdown-menu';
import { Flag } from '@app/ui/components/flag/flag';
import { ChevronDownIcon } from '@app/ui/icons';
diff --git a/src/app/pages/send/send-crypto-asset-form/components/send-crypto-asset-form.layout.tsx b/src/app/pages/send/send-crypto-asset-form/components/send-crypto-asset-form.layout.tsx
index 38c13c25d95..dea87a8c4c4 100644
--- a/src/app/pages/send/send-crypto-asset-form/components/send-crypto-asset-form.layout.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/components/send-crypto-asset-form.layout.tsx
@@ -1,23 +1,23 @@
import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
import { Flex } from 'leather-styles/jsx';
+import { CardContent } from '@app/ui/layout/card/card-content';
+
interface SendCryptoAssetFormLayoutProps {
children: React.ReactNode;
}
export function SendCryptoAssetFormLayout({ children }: SendCryptoAssetFormLayoutProps) {
return (
-
- {children}
-
+
+
+ {children}
+
+
);
}
diff --git a/src/app/pages/send/send-crypto-asset-form/form/brc-20/brc-20-choose-fee.tsx b/src/app/pages/send/send-crypto-asset-form/form/brc-20/brc-20-choose-fee.tsx
index 7ee86e62a8f..e29c6151cd0 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/brc-20/brc-20-choose-fee.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/brc-20/brc-20-choose-fee.tsx
@@ -10,7 +10,6 @@ import { BtcFeeType } from '@shared/models/fees/bitcoin-fees.model';
import { createMoney } from '@shared/models/money.model';
import { RouteUrls } from '@shared/route-urls';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { formFeeRowValue } from '@app/common/send/utils';
import { useGenerateUnsignedNativeSegwitSingleRecipientTx } from '@app/common/transactions/bitcoin/use-generate-bitcoin-tx';
import {
@@ -19,7 +18,6 @@ import {
} from '@app/components/bitcoin-fees-list/bitcoin-fees-list';
import { useBitcoinFeesList } from '@app/components/bitcoin-fees-list/use-bitcoin-fees-list';
import { LoadingSpinner } from '@app/components/loading-spinner';
-import { ModalHeader } from '@app/components/modal-header';
import { BitcoinChooseFee } from '@app/features/bitcoin-choose-fee/bitcoin-choose-fee';
import { useValidateBitcoinSpend } from '@app/features/bitcoin-choose-fee/hooks/use-validate-bitcoin-spend';
import { UtxoResponseItem } from '@app/query/bitcoin/bitcoin-client';
@@ -113,13 +111,6 @@ export function BrcChooseFee() {
}
}
- function onGoBack() {
- setSelectedFeeType(null);
- navigate(-1);
- }
-
- useRouteHeader( );
-
return isLoadingOrder ? (
);
-
return (
-
-
+ props.handleSubmit()}
+ type="submit"
+ >
+ Continue
+
+
- }
- autoComplete="off"
- />
- } name={ticker} symbol={ticker} />
-
-
- 1. Create transfer inscription with amount to send
- 2. Send transfer inscription to recipient of choice
-
- {
- openInNewTab(
- 'https://leather.gitbook.io/guides/bitcoin/sending-brc-20-tokens'
- );
- }}
- textStyle="body.02"
- >
- Learn more
-
-
-
+
+ }
+ >
+
+
+ }
+ autoComplete="off"
+ />
+ } name={tick} symbol={tick} />
+
+
+ 1. Create transfer inscription with amount to send
+ 2. Send transfer inscription to recipient of choice
+
+ {
+ openInNewTab(
+ 'https://leather.gitbook.io/guides/bitcoin/sending-brc-20-tokens'
+ );
+ }}
+ textStyle="body.02"
+ >
+ Learn more
+
+
+
+
-
);
diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx
index 6303f932bb1..8feeb3f3cf2 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx
@@ -4,10 +4,8 @@ import { BtcFeeType } from '@shared/models/fees/bitcoin-fees.model';
import { BitcoinSendFormValues } from '@shared/models/form.model';
import { useLocationStateWithCache } from '@app/common/hooks/use-location-state';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { BitcoinFeesList } from '@app/components/bitcoin-fees-list/bitcoin-fees-list';
import { useBitcoinFeesList } from '@app/components/bitcoin-fees-list/use-bitcoin-fees-list';
-import { ModalHeader } from '@app/components/modal-header';
import { BitcoinChooseFee } from '@app/features/bitcoin-choose-fee/bitcoin-choose-fee';
import { useValidateBitcoinSpend } from '@app/features/bitcoin-choose-fee/hooks/use-validate-bitcoin-spend';
import { UtxoResponseItem } from '@app/query/bitcoin/bitcoin-client';
@@ -26,7 +24,7 @@ export function useBtcChooseFeeState() {
export function BtcChooseFee() {
const { isSendingMax, txValues, utxos } = useBtcChooseFeeState();
const { selectedFeeType, setSelectedFeeType } = useSendBitcoinAssetContextState();
- const { amountAsMoney, onGoBack, previewTransaction } = useBtcChooseFee();
+ const { amountAsMoney, previewTransaction } = useBtcChooseFee();
const { feesList, isLoading } = useBitcoinFeesList({
amount: amountAsMoney,
@@ -41,8 +39,6 @@ export function BtcChooseFee() {
isSendingMax
);
- useRouteHeader( );
-
return (
<>
);
-
return (
-
-
- }
- onSetIsSendingMax={onSetIsSendingMax}
- isSendingMax={isSendingMax}
- switchableAmount={
-
- }
- />
- }
- name={btcBalance.asset.name}
- symbol={symbol}
- />
-
- {currentNetwork.chain.bitcoin.bitcoinNetwork === 'testnet' && (
-
- {'This is a Bitcoin testnet transaction. Funds have no value. '}
-
- Get testnet BTC here ↗
-
-
- )}
-
-
-
+
+ props.handleSubmit()}
+ type="submit"
+ >
+ Continue
+
+
+
+ }
+ >
+
+
+ }
+ onSetIsSendingMax={onSetIsSendingMax}
+ isSendingMax={isSendingMax}
+ switchableAmount={
+
+ }
+ />
+ }
+ name={btcBalance.asset.name}
+ symbol={symbol}
+ />
+
+ {currentNetwork.chain.bitcoin.bitcoinNetwork === 'testnet' && (
+
+ {'This is a Bitcoin testnet transaction. '}
+
+ Get testnet BTC here ↗
+
+
+ )}
+
+
+
{/* This is for testing purposes only, to make sure the form is ready to be submitted. */}
diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-choose-fee.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-choose-fee.tsx
index 55f5dcb07d7..b47a92ffbd3 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-choose-fee.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-choose-fee.tsx
@@ -1,7 +1,4 @@
-import { useNavigate } from 'react-router-dom';
-
import { logger } from '@shared/logger';
-import { BtcFeeType } from '@shared/models/fees/bitcoin-fees.model';
import { createMoney } from '@shared/models/money.model';
import { btcToSat } from '@app/common/money/unit-conversion';
@@ -10,27 +7,20 @@ import { useGenerateUnsignedNativeSegwitSingleRecipientTx } from '@app/common/tr
import { OnChooseFeeArgs } from '@app/components/bitcoin-fees-list/bitcoin-fees-list';
import { useSignBitcoinTx } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks';
-import { useSendBitcoinAssetContextState } from '../../family/bitcoin/components/send-bitcoin-asset-container';
import { useCalculateMaxBitcoinSpend } from '../../family/bitcoin/hooks/use-calculate-max-spend';
import { useSendFormNavigate } from '../../hooks/use-send-form-navigate';
import { useBtcChooseFeeState } from './btc-choose-fee';
export function useBtcChooseFee() {
const { isSendingMax, txValues, utxos } = useBtcChooseFeeState();
- const navigate = useNavigate();
const sendFormNavigate = useSendFormNavigate();
const generateTx = useGenerateUnsignedNativeSegwitSingleRecipientTx();
- const { setSelectedFeeType } = useSendBitcoinAssetContextState();
const calcMaxSpend = useCalculateMaxBitcoinSpend();
const signTx = useSignBitcoinTx();
const amountAsMoney = createMoney(btcToSat(txValues.amount).toNumber(), 'BTC');
return {
amountAsMoney,
- onGoBack() {
- setSelectedFeeType(BtcFeeType.Standard);
- navigate(-1);
- },
async previewTransaction({ feeRate, feeValue, time, isCustomFee }: OnChooseFeeArgs) {
const resp = await generateTx(
diff --git a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx
index 88ed4fa7bee..8fd0b2c8bbb 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx
@@ -1,22 +1,28 @@
import { Outlet, useNavigate } from 'react-router-dom';
+import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
+import BigNumber from 'bignumber.js';
import { Form, Formik, FormikHelpers } from 'formik';
import { Box } from 'leather-styles/jsx';
import { ObjectSchema } from 'yup';
-import { HIGH_FEE_WARNING_LEARN_MORE_URL_STX } from '@shared/constants';
+import { HIGH_FEE_AMOUNT_STX, HIGH_FEE_WARNING_LEARN_MORE_URL_STX } from '@shared/constants';
import { Fees } from '@shared/models/fees/fees.model';
import { StacksSendFormValues } from '@shared/models/form.model';
import { Money } from '@shared/models/money.model';
import { RouteUrls } from '@shared/route-urls';
+import { formatMoney } from '@app/common/money/format-money';
import { FeesRow } from '@app/components/fees-row/fees-row';
import { NonceSetter } from '@app/components/nonce-setter';
-import { HighFeeDrawer } from '@app/features/high-fee-drawer/high-fee-drawer';
+import { HighFeeDialog } from '@app/features/dialogs/high-fee-dialog/high-fee-dialog';
import { useUpdatePersistedSendFormValues } from '@app/features/popup-send-form-restoration/use-update-persisted-send-form-values';
+import { Button } from '@app/ui/components/button/button';
+import { AvailableBalance } from '@app/ui/components/containers/footers/available-balance';
+import { Footer } from '@app/ui/components/containers/footers/footer';
import { Link } from '@app/ui/components/link/link';
+import { Card } from '@app/ui/layout/card/card';
-import { FormFooter } from '../../components/form-footer';
import { MemoField } from '../../components/memo-field';
import { SendCryptoAssetFormLayout } from '../../components/send-crypto-asset-form.layout';
import { StacksRecipientField } from '../../family/stacks/components/stacks-recipient-field';
@@ -33,6 +39,7 @@ interface StacksCommonSendFormProps {
selectedAssetField: React.JSX.Element;
availableTokenBalance: Money;
fees?: Fees;
+ fee?: number | string | BigNumber;
}
export function StacksCommonSendForm({
@@ -42,11 +49,11 @@ export function StacksCommonSendForm({
amountField,
selectedAssetField,
fees,
+ fee,
availableTokenBalance,
}: StacksCommonSendFormProps) {
const navigate = useNavigate();
const { onFormStateChange } = useUpdatePersistedSendFormValues();
-
return (
>
diff --git a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-send-form-confirmation.tsx b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-send-form-confirmation.tsx
index 8bb9e4fb5b7..d91454baed6 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-send-form-confirmation.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-send-form-confirmation.tsx
@@ -1,4 +1,4 @@
-import { Outlet, useNavigate, useParams } from 'react-router-dom';
+import { Outlet, useParams } from 'react-router-dom';
import { deserializeTransaction } from '@stacks/transactions';
import { Box, Stack } from 'leather-styles/jsx';
@@ -6,8 +6,6 @@ import { Box, Stack } from 'leather-styles/jsx';
import { CryptoCurrencies } from '@shared/models/currencies.model';
import { useLocationStateWithCache } from '@app/common/hooks/use-location-state';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { ModalHeader } from '@app/components/modal-header';
import { useStacksBroadcastTransaction } from '@app/features/stacks-transaction-request/hooks/use-stacks-broadcast-transaction';
import { useStacksTransactionSummary } from '@app/features/stacks-transaction-request/hooks/use-stacks-transaction-summary';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
@@ -26,7 +24,6 @@ function useStacksSendFormConfirmationState() {
export function StacksSendFormConfirmation() {
const { tx, decimals, showFeeChangeWarning } = useStacksSendFormConfirmationState();
const { symbol = 'STX' } = useParams();
- const navigate = useNavigate();
const { stacksBroadcastTransaction, isBroadcasting } = useStacksBroadcastTransaction(
symbol.toUpperCase() as CryptoCurrencies,
@@ -51,15 +48,6 @@ export function StacksSendFormConfirmation() {
memoDisplayText,
} = formReviewTxSummary(stacksDeserializedTransaction, symbol, decimals);
- useRouteHeader(
- navigate('../', { relative: 'path', replace: true })}
- title="Review"
- />
- );
-
const feeWarningTooltip = showFeeChangeWarning ? (
) {
// Validate and check high fee warning first
const formErrors = formikHelpers.validateForm();
- if (
- !isShowingHighFeeConfirmation &&
- isEmpty(formErrors) &&
- new BigNumber(values.fee).isGreaterThan(HIGH_FEE_AMOUNT_STX)
- ) {
- setIsShowingHighFeeConfirmation(true);
+ // TODO - check as this seems to only validate HighFees
+ // See PR https://github.com/leather-wallet/extension/pull/3486/
+ if (isEmpty(formErrors) && new BigNumber(values.fee).isGreaterThan(HIGH_FEE_AMOUNT_STX)) {
return false;
}
return true;
diff --git a/src/app/pages/send/send-crypto-asset-form/form/stx/stx-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/stx/stx-send-form.tsx
index 870350795c6..0e95742f203 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/stx/stx-send-form.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/stx/stx-send-form.tsx
@@ -22,6 +22,7 @@ export function StxSendForm() {
sendMaxBalance,
stxFees: fees,
validationSchema,
+ fee,
} = useStxSendForm();
const amountField = (
@@ -47,6 +48,9 @@ export function StxSendForm() {
amountField={amountField}
selectedAssetField={selectedAssetField}
fees={fees}
+ // FIXME 4370 - need to fix this as fee is actually NumberSchema; in FeeValidatorFactoryArgs
+ // this needs to be the STX fee so it can be validated against HIGH_FEE_AMOUNT_STX
+ fee={fee as unknown as string}
availableTokenBalance={availableStxBalance}
/>
);
diff --git a/src/app/pages/send/send-crypto-asset-form/form/stx/use-stx-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/stx/use-stx-send-form.tsx
index 61aee92f800..b726551845c 100644
--- a/src/app/pages/send/send-crypto-asset-form/form/stx/use-stx-send-form.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/form/stx/use-stx-send-form.tsx
@@ -50,16 +50,20 @@ export function useStxSendForm() {
availableTokenBalance: availableStxBalance,
});
+ // FIXME - I don't this this is the fee, should be value.fee or something from the form
+ const fee = stxFeeValidator(availableStxBalance);
+
return {
availableStxBalance,
initialValues,
onFormStateChange,
sendMaxBalance,
stxFees,
+ fee,
validationSchema: yup.object({
amount: stxAmountValidator().concat(stxAvailableBalanceValidator(availableStxBalance)),
- fee: stxFeeValidator(availableStxBalance),
+ fee,
recipient,
memo,
nonce,
diff --git a/src/app/pages/send/send-crypto-asset-form/hooks/use-send-form-navigate.ts b/src/app/pages/send/send-crypto-asset-form/hooks/use-send-form-navigate.ts
index df0de5edb5a..4243f5411d4 100644
--- a/src/app/pages/send/send-crypto-asset-form/hooks/use-send-form-navigate.ts
+++ b/src/app/pages/send/send-crypto-asset-form/hooks/use-send-form-navigate.ts
@@ -14,7 +14,6 @@ interface ConfirmationRouteState {
decimals?: number;
token?: string;
tx: string;
- hasHeaderTitle?: boolean;
}
interface ConfirmationRouteStacksSip10Args {
@@ -49,7 +48,6 @@ export function useSendFormNavigate() {
isSendingMax,
utxos,
values,
- hasHeaderTitle: true,
},
});
},
@@ -67,7 +65,6 @@ export function useSendFormNavigate() {
fee,
feeRowValue,
time,
- hasHeaderTitle: true,
} as ConfirmationRouteState,
});
},
@@ -76,7 +73,6 @@ export function useSendFormNavigate() {
replace: true,
state: {
tx: bytesToHex(tx.serialize()),
- hasHeaderTitle: true,
showFeeChangeWarning,
} as ConfirmationRouteState,
});
diff --git a/src/app/pages/send/send-crypto-asset-form/send-crypto-asset-form.routes.tsx b/src/app/pages/send/send-crypto-asset-form/send-crypto-asset-form.routes.tsx
index 8ad33c31f81..01fec10cac8 100644
--- a/src/app/pages/send/send-crypto-asset-form/send-crypto-asset-form.routes.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/send-crypto-asset-form.routes.tsx
@@ -1,23 +1,23 @@
import { Suspense } from 'react';
-import { Route } from 'react-router-dom';
+import { Outlet, Route } from 'react-router-dom';
import { RouteUrls } from '@shared/route-urls';
-import { BroadcastErrorDrawer } from '@app/components/broadcast-error-drawer/broadcast-error-drawer';
+import { BroadcastErrorDialog } from '@app/components/broadcast-error-dialog/broadcast-error-dialog';
import { SendBtcDisabled } from '@app/components/crypto-assets/choose-crypto-asset/send-btc-disabled';
import { FullPageWithHeaderLoadingSpinner } from '@app/components/loading-spinner';
-import { EditNonceDrawer } from '@app/features/edit-nonce-drawer/edit-nonce-drawer';
+import { EditNonceDialog } from '@app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog';
import { ledgerBitcoinTxSigningRoutes } from '@app/features/ledger/flows/bitcoin-tx-signing/ledger-bitcoin-sign-tx-container';
import { ledgerStacksTxSigningRoutes } from '@app/features/ledger/flows/stacks-tx-signing/ledger-sign-stacks-tx-container';
import { AccountGate } from '@app/routes/account-gate';
+import { Page } from '@app/ui/layout/page/page.layout';
import { BroadcastError } from '../broadcast-error/broadcast-error';
import { ChooseCryptoAsset } from '../choose-crypto-asset/choose-crypto-asset';
-import { SendContainer } from '../send-container';
import { Brc20SentSummary } from '../sent-summary/brc20-sent-summary';
import { BtcSentSummary } from '../sent-summary/btc-sent-summary';
import { StxSentSummary } from '../sent-summary/stx-sent-summary';
-import { RecipientAccountsDrawer } from './components/recipient-accounts-drawer/recipient-accounts-drawer';
+import { RecipientAccountsDialog } from './components/recipient-accounts-dialog/recipient-accounts-dialog';
import { SendBitcoinAssetContainer } from './family/bitcoin/components/send-bitcoin-asset-container';
import { Brc20SendForm } from './form/brc-20/brc20-send-form';
import { Brc20SendFormConfirmation } from './form/brc-20/brc20-send-form-confirmation';
@@ -29,20 +29,26 @@ import { Sip10TokenSendForm } from './form/stacks-sip10/sip10-token-send-form';
import { StacksSendFormConfirmation } from './form/stacks/stacks-send-form-confirmation';
import { StxSendForm } from './form/stx/stx-send-form';
-const recipientAccountsDrawerRoute = (
+const recipientAccountsDialogRoute = (
}
+ element={ }
/>
);
-const editNonceDrawerRoute = } />;
-const broadcastErrorDrawerRoute = (
- } />
+const editNonceDialogRoute = } />;
+const broadcastErrorDialogRoute = (
+ } />
);
export const sendCryptoAssetFormRoutes = (
- }>
+
+
+
+ }
+ >
}
/>
-
}>
}
>
{ledgerBitcoinTxSigningRoutes}
- {recipientAccountsDrawerRoute}
+ {recipientAccountsDialogRoute}
- } />
- } />
+ } />
+ } />
- } />
+ } />
}>
{ledgerBitcoinTxSigningRoutes}
@@ -78,11 +83,10 @@ export const sendCryptoAssetFormRoutes = (
} />
} />
-
}>
- {broadcastErrorDrawerRoute}
- {editNonceDrawerRoute}
- {recipientAccountsDrawerRoute}
+ {broadcastErrorDialogRoute}
+ {editNonceDialogRoute}
+ {recipientAccountsDialogRoute}
{ledgerStacksTxSigningRoutes}
-
}>
- {broadcastErrorDrawerRoute}
- {editNonceDrawerRoute}
- {recipientAccountsDrawerRoute}
+ {broadcastErrorDialogRoute}
+ {editNonceDialogRoute}
+ {recipientAccountsDialogRoute}
}>
{ledgerStacksTxSigningRoutes}
-
} />
);
diff --git a/src/app/pages/send/sent-summary/brc20-sent-summary.tsx b/src/app/pages/send/sent-summary/brc20-sent-summary.tsx
index 6b2748160d4..d610a1318bb 100644
--- a/src/app/pages/send/sent-summary/brc20-sent-summary.tsx
+++ b/src/app/pages/send/sent-summary/brc20-sent-summary.tsx
@@ -5,7 +5,6 @@ import get from 'lodash.get';
import { createMoney } from '@shared/models/money.model';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { HandleOpenStacksTxLinkArgs } from '@app/common/hooks/use-stacks-explorer-link';
import { formatMoney } from '@app/common/money/format-money';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
@@ -17,7 +16,6 @@ import {
InfoCardRow,
InfoCardSeparator,
} from '@app/components/info-card/info-card';
-import { ModalHeader } from '@app/components/modal-header';
import { Callout } from '@app/ui/components/callout/callout';
import { Link } from '@app/ui/components/link/link';
import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
@@ -47,8 +45,6 @@ export function Brc20SentSummary() {
navigate('/');
}
- useRouteHeader( );
-
return (
diff --git a/src/app/pages/send/sent-summary/btc-sent-summary.tsx b/src/app/pages/send/sent-summary/btc-sent-summary.tsx
index 2a641c41ee9..565ab847988 100644
--- a/src/app/pages/send/sent-summary/btc-sent-summary.tsx
+++ b/src/app/pages/send/sent-summary/btc-sent-summary.tsx
@@ -6,7 +6,6 @@ import { HStack, Stack } from 'leather-styles/jsx';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useBitcoinExplorerLink } from '@app/common/hooks/use-bitcoin-explorer-link';
import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer';
import {
InfoCard,
@@ -16,7 +15,6 @@ import {
InfoCardRow,
InfoCardSeparator,
} from '@app/components/info-card/info-card';
-import { ModalHeader } from '@app/components/modal-header';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
@@ -53,8 +51,6 @@ export function BtcSentSummary() {
toast.success('ID copied!');
}
- useRouteHeader( );
-
return (
diff --git a/src/app/pages/send/sent-summary/stx-sent-summary.tsx b/src/app/pages/send/sent-summary/stx-sent-summary.tsx
index a8f1d6e4fda..e9bac0eb7e4 100644
--- a/src/app/pages/send/sent-summary/stx-sent-summary.tsx
+++ b/src/app/pages/send/sent-summary/stx-sent-summary.tsx
@@ -5,7 +5,6 @@ import { HStack, Stack } from 'leather-styles/jsx';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useStacksExplorerLink } from '@app/common/hooks/use-stacks-explorer-link';
import { whenPageMode } from '@app/common/utils';
import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer';
@@ -17,7 +16,6 @@ import {
InfoCardRow,
InfoCardSeparator,
} from '@app/components/info-card/info-card';
-import { ModalHeader } from '@app/components/modal-header';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { ExternalLinkIcon } from '@app/ui/icons/external-link-icon';
@@ -54,8 +52,6 @@ export function StxSentSummary() {
toast.success('ID copied!');
}
- useRouteHeader( );
-
return (
-
-
-
-
- );
-}
diff --git a/src/app/pages/sign-out-confirm/sign-out-confirm.tsx b/src/app/pages/sign-out-confirm/sign-out-confirm.tsx
deleted file mode 100644
index b335ec8ed8a..00000000000
--- a/src/app/pages/sign-out-confirm/sign-out-confirm.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { useNavigate } from 'react-router-dom';
-
-import { RouteUrls } from '@shared/route-urls';
-
-import { useKeyActions } from '@app/common/hooks/use-key-actions';
-import { useLocationState } from '@app/common/hooks/use-location-state';
-import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
-
-import { SignOutConfirmLayout } from './sign-out-confirm.layout';
-
-export function SignOutConfirmDrawer() {
- useBackgroundLocationRedirect();
- const { signOut } = useKeyActions();
- const navigate = useNavigate();
- const backgroundLocation = useLocationState('backgroundLocation');
-
- return (
- {
- void signOut().finally(() => {
- navigate(RouteUrls.Onboarding);
- });
- }}
- onUserSafelyReturnToHomepage={() => navigate(backgroundLocation ?? '..')}
- />
- );
-}
diff --git a/src/app/pages/swap/alex-swap-container.tsx b/src/app/pages/swap/alex-swap-container.tsx
index ec4258915e8..9c63b3d469e 100644
--- a/src/app/pages/swap/alex-swap-container.tsx
+++ b/src/app/pages/swap/alex-swap-container.tsx
@@ -22,8 +22,8 @@ import { defaultFeesMinValuesAsMoney } from '@app/query/stacks/fees/fees.utils';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useGenerateStacksContractCallUnsignedTx } from '@app/store/transactions/contract-call.hooks';
import { useSignStacksTransaction } from '@app/store/transactions/transaction.hooks';
+import { Page } from '@app/ui/layout/page/page.layout';
-import { SwapContainerLayout } from './components/swap-container.layout';
import { SwapForm } from './components/swap-form';
import { generateSwapRoutes } from './generate-swap-routes';
import { useAlexBroadcastSwap } from './hooks/use-alex-broadcast-swap';
@@ -201,12 +201,12 @@ function AlexSwapContainer() {
return (
-
+
-
+
);
}
diff --git a/src/app/pages/swap/components/swap-container.layout.tsx b/src/app/pages/swap/components/swap-container.layout.tsx
deleted file mode 100644
index f91471633a0..00000000000
--- a/src/app/pages/swap/components/swap-container.layout.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Flex } from 'leather-styles/jsx';
-
-import { HasChildren } from '@app/common/has-children';
-import { whenPageMode } from '@app/common/utils';
-
-export function SwapContainerLayout({ children }: HasChildren) {
- return whenPageMode({
- full: (
-
- {children}
-
- ),
- popup: (
-
- {children}
-
- ),
- });
-}
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
deleted file mode 100644
index eb40bfdcbf4..00000000000
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Stack, StackProps } from 'leather-styles/jsx';
-
-export function SwapAssetListLayout({ children }: StackProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
index 32c2028fd89..66e74b55051 100644
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
+++ b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
@@ -2,6 +2,7 @@ import { useNavigate } from 'react-router-dom';
import BigNumber from 'bignumber.js';
import { useFormikContext } from 'formik';
+import { Stack } from 'leather-styles/jsx';
import { createMoney } from '@shared/models/money.model';
import { isUndefined } from '@shared/utils';
@@ -13,7 +14,6 @@ import { useSwapContext } from '@app/pages/swap/swap.context';
import { SwapAsset, SwapFormValues } from '../../hooks/use-swap-form';
import { useSwapChooseAssetState } from '../swap-choose-asset';
import { SwapAssetItem } from './swap-asset-item';
-import { SwapAssetListLayout } from './swap-asset-list.layout';
interface SwapAssetList {
assets: SwapAsset[];
@@ -46,6 +46,7 @@ export function SwapAssetList({ assets }: SwapAssetList) {
await setFieldValue('swapAssetTo', asset);
setFieldError('swapAssetTo', undefined);
}
+
navigate(-1);
if (from && to && values.swapAmountFrom) {
const toAmount = await fetchToAmount(from, to, values.swapAmountFrom);
@@ -64,7 +65,7 @@ export function SwapAssetList({ assets }: SwapAssetList) {
}
return (
-
+
{selectableAssets.map(asset => (
onChooseAsset(asset)}
/>
))}
-
+
);
}
diff --git a/src/app/pages/swap/swap-choose-asset/swap-choose-asset.tsx b/src/app/pages/swap/swap-choose-asset/swap-choose-asset.tsx
index d095c762849..94fbb94eb1c 100644
--- a/src/app/pages/swap/swap-choose-asset/swap-choose-asset.tsx
+++ b/src/app/pages/swap/swap-choose-asset/swap-choose-asset.tsx
@@ -4,7 +4,9 @@ import { SwapSelectors } from '@tests/selectors/swap.selectors';
import { Box, styled } from 'leather-styles/jsx';
import get from 'lodash.get';
-import { BaseDrawer } from '@app/components/drawer/base-drawer';
+import { RouteUrls } from '@shared/route-urls';
+
+import { Dialog } from '@app/ui/components/containers/dialog/dialog';
import { useSwapContext } from '../swap.context';
import { SwapAssetList } from './components/swap-asset-list';
@@ -22,28 +24,15 @@ export function SwapChooseAsset() {
const isFromList = swapListType === 'from';
- const title = isFromList ? (
- <>
- Choose asset
-
- to swap
- >
- ) : (
- <>
- Choose asset
-
- to receive
- >
- );
+ const title = isFromList ? 'Choose asset to swap' : 'Choose asset to receive';
return (
- navigate(-1)}>
-
-
- {title}
-
+ navigate(RouteUrls.Swap)}>
+ {/* try replace below height with dialog and get rid of box */}
+
+ {title}
-
+
);
}
diff --git a/src/app/pages/swap/swap-review/swap-review.tsx b/src/app/pages/swap/swap-review/swap-review.tsx
index accef3a66a9..71ee8a184d2 100644
--- a/src/app/pages/swap/swap-review/swap-review.tsx
+++ b/src/app/pages/swap/swap-review/swap-review.tsx
@@ -3,8 +3,6 @@ import { Outlet } from 'react-router-dom';
import { SwapSelectors } from '@tests/selectors/swap.selectors';
import { LoadingKeys, useLoading } from '@app/common/hooks/use-loading';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { ModalHeader } from '@app/components/modal-header';
import { Button } from '@app/ui/components/button/button';
import { SwapAssetsPair } from '../components/swap-assets-pair/swap-assets-pair';
@@ -18,8 +16,6 @@ export function SwapReview() {
const { onSubmitSwap } = useSwapContext();
const { isLoading } = useLoading(LoadingKeys.SUBMIT_SWAP_TRANSACTION);
- useRouteHeader( , true);
-
return (
<>
diff --git a/src/app/pages/swap/swap.tsx b/src/app/pages/swap/swap.tsx
index 64b8cb5fce4..640dac5d980 100644
--- a/src/app/pages/swap/swap.tsx
+++ b/src/app/pages/swap/swap.tsx
@@ -6,9 +6,7 @@ import { useFormikContext } from 'formik';
import { isUndefined } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { LoadingSpinner } from '@app/components/loading-spinner';
-import { ModalHeader } from '@app/components/modal-header';
import { Button } from '@app/ui/components/button/button';
import { SwapContentLayout } from './components/swap-content.layout';
@@ -21,8 +19,6 @@ export function Swap() {
const { isFetchingExchangeRate, swappableAssetsFrom } = useSwapContext();
const { dirty, isValid, setFieldValue, values } = useFormikContext();
- useRouteHeader( , true);
-
useAsync(async () => {
if (isUndefined(values.swapAssetFrom))
return await setFieldValue('swapAssetFrom', swappableAssetsFrom[0]);
diff --git a/src/app/pages/transaction-request/transaction-request.tsx b/src/app/pages/transaction-request/transaction-request.tsx
index 55aea73d0dd..c521a116292 100644
--- a/src/app/pages/transaction-request/transaction-request.tsx
+++ b/src/app/pages/transaction-request/transaction-request.tsx
@@ -1,4 +1,4 @@
-import { memo } from 'react';
+import { memo, useState } from 'react';
import { Outlet, useNavigate } from 'react-router-dom';
import { Formik, FormikHelpers } from 'formik';
@@ -13,13 +13,11 @@ import { RouteUrls } from '@shared/route-urls';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useOnMount } from '@app/common/hooks/use-on-mount';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { stxFeeValidator } from '@app/common/validation/forms/fee-validators';
import { nonceValidator } from '@app/common/validation/nonce-validators';
import { NonceSetter } from '@app/components/nonce-setter';
-import { PopupHeader } from '@app/features/current-account/popup-header';
+import { HighFeeDialog } from '@app/features/dialogs/high-fee-dialog/high-fee-dialog';
import { RequestingTabClosedWarningMessage } from '@app/features/errors/requesting-tab-closed-error-msg';
-import { HighFeeDrawer } from '@app/features/high-fee-drawer/high-fee-drawer';
import { ContractCallDetails } from '@app/features/stacks-transaction-request/contract-call-details/contract-call-details';
import { ContractDeployDetails } from '@app/features/stacks-transaction-request/contract-deploy-details/contract-deploy-details';
import { FeeForm } from '@app/features/stacks-transaction-request/fee-form';
@@ -42,6 +40,8 @@ import {
import { Link } from '@app/ui/components/link/link';
function TransactionRequestBase() {
+ const [isShowingHighFeeConfirmation, setIsShowingHighFeeConfirmation] = useState(false);
+
const transactionRequest = useTransactionRequestState();
const unsignedTx = useUnsignedStacksTransactionBaseState();
const { data: stxFees } = useCalculateStacksTxFees(unsignedTx.transaction);
@@ -52,8 +52,6 @@ function TransactionRequestBase() {
const navigate = useNavigate();
const { stacksBroadcastTransaction } = useStacksBroadcastTransaction('STX');
- useRouteHeader( );
-
useOnMount(() => void analytics.track('view_transaction_signing'));
async function onSubmit(
@@ -119,8 +117,14 @@ function TransactionRequestBase() {
Edit nonce
-
-
+ setIsShowingHighFeeConfirmation(true)}
+ />
+
+
>
)}
diff --git a/src/app/pages/unlock.tsx b/src/app/pages/unlock.tsx
index 71135790040..8906f5f5b98 100644
--- a/src/app/pages/unlock.tsx
+++ b/src/app/pages/unlock.tsx
@@ -1,56 +1,17 @@
-import { useEffect } from 'react';
import { Outlet, useNavigate } from 'react-router-dom';
-import { Box } from 'leather-styles/jsx';
-
-import { WALLET_ENVIRONMENT } from '@shared/environment';
import { RouteUrls } from '@shared/route-urls';
-import { closeWindow } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { isFullPageMode, isPopupMode } from '@app/common/utils';
-import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
-import { Header } from '@app/components/header';
import { RequestPassword } from '@app/components/request-password';
-import { useNewBrandApprover } from '@app/store/settings/settings.selectors';
export function Unlock() {
const navigate = useNavigate();
- useRouteHeader();
-
- const { hasApprovedNewBrand } = useNewBrandApprover();
-
- useEffect(() => {
- if (!hasApprovedNewBrand && isPopupMode() && WALLET_ENVIRONMENT !== 'testing') {
- openIndexPageInNewTab('/unlock/we-have-a-new-name');
- closeWindow();
- }
- if (!hasApprovedNewBrand && isFullPageMode()) {
- navigate('./we-have-a-new-name');
- }
- }, [hasApprovedNewBrand, navigate]);
-
const handleSuccess = () => navigate(RouteUrls.Home);
return (
<>
- {/* Hide the logo when user hasn't consented yet */}
- {!hasApprovedNewBrand && (
-
- )}
-
-
- Your
-
- session is locked
- >
- }
- caption="Enter the password you set on this device"
- onSuccess={handleSuccess}
- />
+
>
);
diff --git a/src/app/pages/update-profile-request/update-profile-request.tsx b/src/app/pages/update-profile-request/update-profile-request.tsx
index 44602f339bf..3369a3f4440 100644
--- a/src/app/pages/update-profile-request/update-profile-request.tsx
+++ b/src/app/pages/update-profile-request/update-profile-request.tsx
@@ -2,8 +2,6 @@ import { memo } from 'react';
import { closeWindow, isUndefined } from '@shared/utils';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { PopupHeader } from '@app/features/current-account/popup-header';
import { useOnOriginTabClose } from '@app/routes/hooks/use-on-tab-closed';
import {
useIsProfileUpdateRequestValid,
@@ -18,8 +16,6 @@ function ProfileUpdateRequestBase() {
const validProfileUpdateRequest = useIsProfileUpdateRequestValid();
const { requestToken } = useProfileUpdateRequestSearchParams();
- useRouteHeader( );
-
useOnOriginTabClose(() => closeWindow());
if (isUndefined(validProfileUpdateRequest) || !validProfileUpdateRequest || !requestToken)
return (
diff --git a/src/app/pages/view-secret-key/components/view-secret-key.content.tsx b/src/app/pages/view-secret-key/components/view-secret-key.content.tsx
deleted file mode 100644
index ea124ff4a10..00000000000
--- a/src/app/pages/view-secret-key/components/view-secret-key.content.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { styled } from 'leather-styles/jsx';
-
-export function ViewSecretKeyContent(): React.JSX.Element {
- return (
- <>
-
- Your Secret Key
-
-
- These 24 words are your Secret Key. They create your account, and you sign in on different
- devices with them. Make sure to save these somewhere safe.
-
-
-
-
- If you lose these words, you lose your account.
-
- >
- );
-}
diff --git a/src/app/pages/view-secret-key/view-secret-key.tsx b/src/app/pages/view-secret-key/view-secret-key.tsx
index 5921326d62b..f2e0684848d 100644
--- a/src/app/pages/view-secret-key/view-secret-key.tsx
+++ b/src/app/pages/view-secret-key/view-secret-key.tsx
@@ -1,26 +1,17 @@
import { useEffect, useState } from 'react';
-import { Outlet, useNavigate } from 'react-router-dom';
-
-import { RouteUrls } from '@shared/route-urls';
+import { Outlet } from 'react-router-dom';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Header } from '@app/components/header';
import { RequestPassword } from '@app/components/request-password';
-import { TwoColumnLayout } from '@app/components/secret-key/two-column.layout';
-import { SecretKeyDisplayer } from '@app/features/secret-key-displayer/secret-key-displayer';
+import { SecretKey } from '@app/features/secret-key-displayer/secret-key-displayer';
import { useDefaultWalletSecretKey } from '@app/store/in-memory-key/in-memory-key.selectors';
-
-import { ViewSecretKeyContent } from './components/view-secret-key.content';
+import { TwoColumnLayout } from '@app/ui/pages/two-column.layout';
export function ViewSecretKey() {
const analytics = useAnalytics();
- const navigate = useNavigate();
const defaultWalletSecretKey = useDefaultWalletSecretKey();
const [showSecretKey, setShowSecretKey] = useState(false);
- useRouteHeader( navigate(RouteUrls.Home)} />);
-
useEffect(() => {
void analytics.page('view', '/save-secret-key');
}, [analytics]);
@@ -28,25 +19,28 @@ export function ViewSecretKey() {
if (showSecretKey) {
return (
}
- rightColumn={ }
- />
- );
- }
-
- return (
- <>
-
- View
+ Your Secret Key
+ >
+ }
+ content={
+ <>
+ These 24 words are your Secret Key. They create your account, and you sign in on
+ different devices with them. Make sure to save these somewhere safe.
- Secret Key
+ If you lose these words, you lose your account.
>
}
- caption="Enter the password you set on this device"
- onSuccess={() => setShowSecretKey(true)}
- />
+ >
+
+
+ );
+ }
+
+ return (
+ <>
+ setShowSecretKey(true)} />
>
);
diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx
index d53359792b8..5e5e2359d68 100644
--- a/src/app/routes/app-routes.tsx
+++ b/src/app/routes/app-routes.tsx
@@ -12,11 +12,11 @@ import { RouteUrls } from '@shared/route-urls';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { AddNetwork } from '@app/features/add-network/add-network';
import { Container } from '@app/features/container/container';
-import { EditNonceDrawer } from '@app/features/edit-nonce-drawer/edit-nonce-drawer';
-import { IncreaseBtcFeeDrawer } from '@app/features/increase-fee-drawer/increase-btc-fee-drawer';
-import { IncreaseFeeSentDrawer } from '@app/features/increase-fee-drawer/increase-fee-sent-drawer';
-import { IncreaseStxFeeDrawer } from '@app/features/increase-fee-drawer/increase-stx-fee-drawer';
-import { leatherIntroDialogRoutes } from '@app/features/leather-intro-dialog/leather-intro-dialog';
+import { EditNonceDialog } from '@app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog';
+import { IncreaseBtcFeeDialog } from '@app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog';
+import { IncreaseFeeSentDialog } from '@app/features/dialogs/increase-fee-dialog/increase-fee-sent-dialog';
+import { IncreaseStxFeeDialog } from '@app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog';
+import { leatherIntroDialogRoutes } from '@app/features/dialogs/leather-intro-dialog/leather-intro-dialog';
import { ledgerBitcoinTxSigningRoutes } from '@app/features/ledger/flows/bitcoin-tx-signing/ledger-bitcoin-sign-tx-container';
import { ledgerJwtSigningRoutes } from '@app/features/ledger/flows/jwt-signing/ledger-sign-jwt.routes';
import { requestBitcoinKeysRoutes } from '@app/features/ledger/flows/request-bitcoin-keys/ledger-request-bitcoin-keys';
@@ -51,7 +51,6 @@ import { AccountGate } from '@app/routes/account-gate';
import { receiveRoutes } from '@app/routes/receive-routes';
import { legacyRequestRoutes } from '@app/routes/request-routes';
import { rpcRequestRoutes } from '@app/routes/rpc-routes';
-import { settingsRoutes } from '@app/routes/settings-routes';
import { OnboardingGate } from './onboarding-gate';
@@ -66,7 +65,6 @@ export function AppRoutes() {
export const homePageModalRoutes = (
<>
- {settingsRoutes}
{receiveRoutes}
{ledgerStacksTxSigningRoutes}
{ledgerBitcoinTxSigningRoutes}
@@ -92,13 +90,13 @@ function useAppRoutes() {
} />
- }>
+ }>
{ledgerStacksTxSigningRoutes}
- }>
+ }>
{ledgerBitcoinTxSigningRoutes}
- } />
+ } />
{ledgerStacksTxSigningRoutes}
@@ -183,8 +181,6 @@ function useAppRoutes() {
}
>
- {settingsRoutes}
-
} />
} />
@@ -196,7 +192,6 @@ function useAppRoutes() {
}
>
- {settingsRoutes}
} />
@@ -209,11 +204,8 @@ function useAppRoutes() {
}
- >
- {settingsRoutes}
-
+ />
}>
- {settingsRoutes}
{leatherIntroDialogRoutes}
@@ -237,7 +229,7 @@ function useAppRoutes() {
}
>
- } />
+ } />
- } />
+ } />
} />
} />
} />
- } />
+ } />
} />
);
diff --git a/src/app/routes/request-routes.tsx b/src/app/routes/request-routes.tsx
index 1b0e931009b..1cd1886af83 100644
--- a/src/app/routes/request-routes.tsx
+++ b/src/app/routes/request-routes.tsx
@@ -3,8 +3,8 @@ import { Route } from 'react-router-dom';
import { RouteUrls } from '@shared/route-urls';
-import { BroadcastErrorDrawer } from '@app/components/broadcast-error-drawer/broadcast-error-drawer';
-import { EditNonceDrawer } from '@app/features/edit-nonce-drawer/edit-nonce-drawer';
+import { BroadcastErrorDialog } from '@app/components/broadcast-error-dialog/broadcast-error-dialog';
+import { EditNonceDialog } from '@app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog';
import { ledgerStacksMessageSigningRoutes } from '@app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg.routes';
import { ledgerStacksTxSigningRoutes } from '@app/features/ledger/flows/stacks-tx-signing/ledger-sign-stacks-tx-container';
import { PsbtRequest } from '@app/pages/psbt-request/psbt-request';
@@ -27,8 +27,8 @@ export const legacyRequestRoutes = (
}
>
{ledgerStacksTxSigningRoutes}
- } />
- } />
+ } />
+ } />
- } />
- } />
- } />
-
-);
diff --git a/src/app/store/networks/networks.ts b/src/app/store/networks/networks.ts
index 71e3b192529..db70acf03de 100644
--- a/src/app/store/networks/networks.ts
+++ b/src/app/store/networks/networks.ts
@@ -9,6 +9,8 @@ import { storeAtom } from '..';
import { selectCurrentNetworkId, selectNetworks } from './networks.selectors';
import { findMatchingNetworkKey } from './networks.utils';
+// TODO as about this as it's depreacted but not sure what to do instead
+// PR https://github.com/leather-wallet/extension/pull/3017
/** @deprecated */
export const currentNetworkAtom = atom(get => {
const store = get(storeAtom);
diff --git a/src/app/store/settings/settings.selectors.ts b/src/app/store/settings/settings.selectors.ts
index 34862abfb69..4103be10dda 100644
--- a/src/app/store/settings/settings.selectors.ts
+++ b/src/app/store/settings/settings.selectors.ts
@@ -2,9 +2,7 @@ import { useSelector } from 'react-redux';
import { createSelector } from '@reduxjs/toolkit';
-import { RootState, useAppDispatch } from '@app/store';
-
-import { settingsSlice } from './settings.slice';
+import { RootState } from '@app/store';
const selectSettings = (state: RootState) => state.settings;
@@ -40,19 +38,3 @@ const selectDismissedMessageIds = createSelector(
export function useDismissedMessageIds() {
return useSelector(selectDismissedMessageIds);
}
-
-const selectHasApprovedNewBrand = createSelector(
- selectSettings,
- state => !!state.hasApprovedNewBrand
-);
-
-export function useNewBrandApprover() {
- const hasApprovedNewBrand = useSelector(selectHasApprovedNewBrand);
- const dispatch = useAppDispatch();
- return {
- hasApprovedNewBrand,
- userApprovedNewBrand() {
- dispatch(settingsSlice.actions.setHasApprovedNewBrand());
- },
- };
-}
diff --git a/src/app/store/settings/settings.slice.ts b/src/app/store/settings/settings.slice.ts
index be0960dca6a..36105a6b890 100644
--- a/src/app/store/settings/settings.slice.ts
+++ b/src/app/store/settings/settings.slice.ts
@@ -7,15 +7,12 @@ interface InitialState {
userSelectedTheme: UserSelectedTheme;
hasAllowedAnalytics: HasAcceptedAnalytics;
dismissedMessages: string[];
- hasApprovedNewBrand: boolean;
}
const initialState: InitialState = {
userSelectedTheme: 'system',
hasAllowedAnalytics: null,
dismissedMessages: [],
- // Defaults to true, as this is undefined for existing users
- hasApprovedNewBrand: true,
};
export const settingsSlice = createSlice({
@@ -35,11 +32,5 @@ export const settingsSlice = createSlice({
resetMessages(state) {
state.dismissedMessages = [];
},
- setHasApprovedNewBrand(state) {
- state.hasApprovedNewBrand = true;
- },
- resetHasApprovedNewBrand(state) {
- state.hasApprovedNewBrand = false;
- },
},
});
diff --git a/src/app/store/ui/ui.hooks.ts b/src/app/store/ui/ui.hooks.ts
index e8344c96800..bde03bc5c23 100644
--- a/src/app/store/ui/ui.hooks.ts
+++ b/src/app/store/ui/ui.hooks.ts
@@ -1,30 +1,6 @@
import { useAtom } from 'jotai';
-import {
- errorStackTraceState,
- loadingState,
- routeHeaderState,
- showHighFeeConfirmationState,
- showSettingsStore,
- showSwitchAccountsState,
- showTxSettingsCallback,
-} from './ui';
-
-export function useShowHighFeeConfirmationState() {
- return useAtom(showHighFeeConfirmationState);
-}
-
-export function useShowSwitchAccountsState() {
- return useAtom(showSwitchAccountsState);
-}
-
-export function useShowSettingsStore() {
- return useAtom(showSettingsStore);
-}
-
-export function useShowTxSettingsCallback() {
- return useAtom(showTxSettingsCallback);
-}
+import { errorStackTraceState, loadingState } from './ui';
export function useLoadingState(key: string) {
return useAtom(loadingState(key));
@@ -33,7 +9,3 @@ export function useLoadingState(key: string) {
export function useErrorStackTraceState() {
return useAtom(errorStackTraceState);
}
-
-export function useRouteHeaderState() {
- return useAtom(routeHeaderState);
-}
diff --git a/src/app/store/ui/ui.ts b/src/app/store/ui/ui.ts
index bbcd2eaa5f6..ea1ad46c9c9 100644
--- a/src/app/store/ui/ui.ts
+++ b/src/app/store/ui/ui.ts
@@ -9,15 +9,4 @@ export const loadingState = atomFamily(_param => {
return anAtom;
});
-// TODO: refactor into atom family
-export const showSwitchAccountsState = atom(false);
-
-export const showHighFeeConfirmationState = atom(false);
-
-export const showSettingsStore = atom(false);
-
-export const showTxSettingsCallback = atom<(() => Promise) | undefined>(undefined);
-
export const errorStackTraceState = atom(null);
-
-export const routeHeaderState = atom(null);
diff --git a/src/app/components/account/account-avatar-item.tsx b/src/app/ui/components/account/account-avatar/account-avatar-item.tsx
similarity index 76%
rename from src/app/components/account/account-avatar-item.tsx
rename to src/app/ui/components/account/account-avatar/account-avatar-item.tsx
index a6470aca3de..f0b4ecdfa59 100644
--- a/src/app/components/account/account-avatar-item.tsx
+++ b/src/app/ui/components/account/account-avatar/account-avatar-item.tsx
@@ -1,6 +1,6 @@
import { memo } from 'react';
-import { AccountAvatar } from '@app/components/account/account-avatar';
+import { AccountAvatar } from '@app/ui/components/account/account-avatar/account-avatar';
interface AccountAvatarItemProps {
publicKey: string;
diff --git a/src/app/components/account/account-avatar.tsx b/src/app/ui/components/account/account-avatar/account-avatar.tsx
similarity index 100%
rename from src/app/components/account/account-avatar.tsx
rename to src/app/ui/components/account/account-avatar/account-avatar.tsx
diff --git a/src/app/ui/components/account/account.card.stories.tsx b/src/app/ui/components/account/account.card.stories.tsx
new file mode 100644
index 00000000000..8ae4327afc7
--- /dev/null
+++ b/src/app/ui/components/account/account.card.stories.tsx
@@ -0,0 +1,33 @@
+import type { Meta } from '@storybook/react';
+import { Flex } from 'leather-styles/jsx';
+
+import { ActionButton } from '@app/ui/components/account/action-button';
+import { ArrowDownIcon, ArrowUpIcon, PlusIcon, SwapIcon } from '@app/ui/icons';
+
+import { AccountCard as Component } from './account.card';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Layout/AccountCard',
+};
+
+export default meta;
+
+export function AccountCard() {
+ return (
+ >}
+ toggleSwitchAccount={() => null}
+ >
+
+ } label="Send" />
+ } label="Receive" />
+ } label="Buy" />
+ } label="Swap" />
+
+
+ );
+}
diff --git a/src/app/ui/components/account/account.card.tsx b/src/app/ui/components/account/account.card.tsx
new file mode 100644
index 00000000000..ffda04dada1
--- /dev/null
+++ b/src/app/ui/components/account/account.card.tsx
@@ -0,0 +1,66 @@
+import { ReactNode } from 'react';
+
+import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+import { Box, Divider, Flex, styled } from 'leather-styles/jsx';
+
+import { Link } from '@app/ui/components/link/link';
+import { ChevronDownIcon } from '@app/ui/icons';
+
+interface AccountCardProps {
+ name: string;
+ balance: string;
+ children: ReactNode;
+ switchAccount: ReactNode;
+ toggleSwitchAccount(): void;
+}
+
+export function AccountCard({
+ name,
+ balance,
+ switchAccount,
+ toggleSwitchAccount,
+ children,
+}: AccountCardProps) {
+ return (
+
+
+
+
+ {name}
+
+
+
+
+
+
+
+
+ {balance}
+
+
+ {switchAccount}
+
+ {children}
+
+
+ );
+}
diff --git a/src/app/pages/home/components/action-button.tsx b/src/app/ui/components/account/action-button.tsx
similarity index 63%
rename from src/app/pages/home/components/action-button.tsx
rename to src/app/ui/components/account/action-button.tsx
index 0c1234c0f80..085b2a51562 100644
--- a/src/app/pages/home/components/action-button.tsx
+++ b/src/app/ui/components/account/action-button.tsx
@@ -1,9 +1,8 @@
import { Flex, styled } from 'leather-styles/jsx';
+import AccessibleIcon from '@app/ui/components/avatar-icon/accessible-icon';
import { Button } from '@app/ui/components/button/button';
-import AccessibleIcon from './accessible-icon';
-
interface ActionButtonProps extends React.ComponentProps {
icon: React.ReactNode;
label: string;
@@ -11,10 +10,17 @@ interface ActionButtonProps extends React.ComponentProps {
export function ActionButton({ icon, label, ...rest }: ActionButtonProps) {
return (
-
+
{icon}
- {label}
+ {label}
);
diff --git a/src/app/pages/home/components/accessible-icon.tsx b/src/app/ui/components/avatar-icon/accessible-icon.tsx
similarity index 100%
rename from src/app/pages/home/components/accessible-icon.tsx
rename to src/app/ui/components/avatar-icon/accessible-icon.tsx
diff --git a/src/app/ui/components/bullet-separator/bullet-separator.tsx b/src/app/ui/components/bullet-separator/bullet-separator.tsx
index 9d6c7f1213e..a403ed1e79e 100644
--- a/src/app/ui/components/bullet-separator/bullet-separator.tsx
+++ b/src/app/ui/components/bullet-separator/bullet-separator.tsx
@@ -7,7 +7,7 @@ export function BulletOperator(props: CircleProps) {
= {
@@ -39,34 +40,6 @@ export const Disabled: Story = {
},
};
-// TODO: Remove invert code
-export const InvertSolid: Story = {
- parameters: {
- backgrounds: { default: 'leather-dark-mode' },
- controls: { include: [] },
- },
- args: {
- children: 'Button',
- invert: true,
- size: 'md',
- variant: 'solid',
- },
-};
-
-// TODO: Remove invert code
-export const InvertOutline: Story = {
- parameters: {
- backgrounds: { default: 'leather-dark-mode' },
- controls: { include: [] },
- },
- args: {
- children: 'Button',
- invert: true,
- size: 'md',
- variant: 'outline',
- },
-};
-
export const WithIcons: Story = {
parameters: {
controls: { include: ['size', 'variant'] },
diff --git a/src/app/ui/components/button/button.tsx b/src/app/ui/components/button/button.tsx
index e7bd05cb093..8c521b60dac 100644
--- a/src/app/ui/components/button/button.tsx
+++ b/src/app/ui/components/button/button.tsx
@@ -7,10 +7,11 @@ type ButtonProps = Omit, keyof ButtonV
ButtonVariantProps;
export function Button(props: ButtonProps) {
- const { children, fullWidth, invert, size, trigger, type = 'button', variant, ...rest } = props;
+ const { children, fullWidth, size, trigger, invert, type = 'button', variant, ...rest } = props;
+ // pete - not sure we need this invert but it could be thje key difference
return (
diff --git a/src/app/ui/components/containers/container.layout.tsx b/src/app/ui/components/containers/container.layout.tsx
new file mode 100644
index 00000000000..87f039aad96
--- /dev/null
+++ b/src/app/ui/components/containers/container.layout.tsx
@@ -0,0 +1,30 @@
+import { radixBaseCSS } from '@radix-ui/themes/styles.css';
+import { css } from 'leather-styles/css';
+import { Flex } from 'leather-styles/jsx';
+
+interface ContainerLayoutProps {
+ children: React.JSX.Element | React.JSX.Element[];
+ header: React.JSX.Element | null;
+ variant: string;
+}
+// better to keep this component for use in storybook demos
+export function ContainerLayout({ children, header, variant }: ContainerLayoutProps) {
+ // no header still needs to have space I think - check on landing pages
+ return (
+
+ {header}
+
+ {children}
+
+
+ );
+}
diff --git a/src/app/ui/components/containers/dialog/dialog.stories.tsx b/src/app/ui/components/containers/dialog/dialog.stories.tsx
new file mode 100644
index 00000000000..db0b1f5f8d9
--- /dev/null
+++ b/src/app/ui/components/containers/dialog/dialog.stories.tsx
@@ -0,0 +1,15 @@
+import type { Meta } from '@storybook/react';
+
+import { Dialog as Component, RadixDialogProps } from './dialog';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Containers/Dialog',
+};
+
+export default meta;
+
+export function Dialog(args: RadixDialogProps) {
+ return ;
+}
diff --git a/src/app/ui/components/containers/dialog/dialog.tsx b/src/app/ui/components/containers/dialog/dialog.tsx
new file mode 100644
index 00000000000..85a99efa421
--- /dev/null
+++ b/src/app/ui/components/containers/dialog/dialog.tsx
@@ -0,0 +1,61 @@
+import { JSXElementConstructor, ReactElement, ReactNode, cloneElement } from 'react';
+
+import * as RadixDialog from '@radix-ui/react-dialog';
+import { css } from 'leather-styles/css';
+
+import { CardContent } from '@app/ui/layout/card/card-content';
+
+export interface DialogProps {
+ isShowing: boolean;
+ onClose(): void;
+}
+export interface RadixDialogProps extends DialogProps {
+ children: ReactNode;
+ footer?: ReactNode;
+ header?: ReactElement>;
+ onGoBack?(): void;
+}
+
+export function Dialog({ children, footer, header, onClose, isShowing }: RadixDialogProps) {
+ if (!isShowing) return null;
+
+ return (
+
+
+
+
+ {header && cloneElement(header, { onClose })}
+
+ {children}
+ {footer}
+
+
+
+
+ );
+}
diff --git a/src/app/components/available-balance.tsx b/src/app/ui/components/containers/footers/available-balance.tsx
similarity index 62%
rename from src/app/components/available-balance.tsx
rename to src/app/ui/components/containers/footers/available-balance.tsx
index 864b7ef15a8..37d9041d638 100644
--- a/src/app/components/available-balance.tsx
+++ b/src/app/ui/components/containers/footers/available-balance.tsx
@@ -1,17 +1,17 @@
import { Box, Flex, HStack, styled } from 'leather-styles/jsx';
-import { Money } from '@shared/models/money.model';
-
-import { formatMoney } from '@app/common/money/format-money';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
import { InfoCircleIcon } from '@app/ui/icons/info-circle-icon';
-export function AvailableBalance(props: { balance: Money; balanceTooltipLabel?: string }) {
- const {
- balance,
- balanceTooltipLabel = 'Amount that is immediately available for use after taking into account any pending transactions or holds placed on your account by the protocol.',
- } = props;
+interface AvailableBalanceProps {
+ balance: string;
+ balanceTooltipLabel?: string;
+}
+export function AvailableBalance({
+ balance,
+ balanceTooltipLabel = 'Amount that is immediately available for use after taking into account any pending transactions or holds placed on your account by the protocol.',
+}: AvailableBalanceProps) {
return (
@@ -25,7 +25,7 @@ export function AvailableBalance(props: { balance: Money; balanceTooltipLabel?:
- {formatMoney(balance)}
+ {balance}
);
diff --git a/src/app/ui/components/containers/footers/footer.stories.tsx b/src/app/ui/components/containers/footers/footer.stories.tsx
new file mode 100644
index 00000000000..e4c58026b88
--- /dev/null
+++ b/src/app/ui/components/containers/footers/footer.stories.tsx
@@ -0,0 +1,153 @@
+import type { Meta } from '@storybook/react';
+import { Flex, styled } from 'leather-styles/jsx';
+
+import { Button } from '@app/ui/components/button/button';
+import { AvailableBalance } from '@app/ui/components/containers/footers/available-balance';
+
+import { Footer as Component } from './footer';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Containers/Footer',
+ parameters: {
+ controls: {
+ disable: true,
+ // TODO try get rid of these empty controls
+ // https://github.com/storybookjs/storybook/issues/24422
+ hideNoControlsWarning: true,
+ },
+ },
+};
+
+export default meta;
+
+export function Footer() {
+ return (
+
+ null}>
+ Create new account
+
+
+ );
+}
+
+export function SignOutConfirmFooter() {
+ return (
+
+
+ null}>
+ Cancel
+
+ null}
+ type="submit"
+ >
+ Sign out
+
+
+
+ );
+}
+
+export function ReceiveTokensFooter() {
+ return (
+
+ null}>
+ Copy address
+
+
+ );
+}
+
+export function RequestPasswordFooter() {
+ return (
+
+ null}>Continue
+
+ );
+}
+
+export function FooterWithText() {
+ return (
+
+ null}>
+ Continue
+
+
+
+
+ Leather Wallet will now be provided by Leather Wallet LLC [a subsidiary of Nassau Machines
+ Inc]. Please review and accept Leather Wallet{' '}
+
+ Terms of Service
+ {' '}
+ and{' '}
+
+ Privacy Policy
+
+ .
+
+
+
+ );
+}
+
+export function FooterWithLink() {
+ return (
+
+ null}>
+ Button
+
+
+
+ {/* use new
+ View all addresses
+
+
+
+ );
+}
+
+export function FooterWithBalance() {
+ return (
+
+ null} type="submit">
+ Button
+
+
+
+ );
+}
+
+export function FooterWithBalancesAbove() {
+ return (
+
+
+ 0.00048208 BTC
+ $ 1,100.00
+
+ null} type="submit">
+ Button
+
+
+ );
+}
diff --git a/src/app/ui/components/containers/footers/footer.tsx b/src/app/ui/components/containers/footers/footer.tsx
new file mode 100644
index 00000000000..ef1668a3d2e
--- /dev/null
+++ b/src/app/ui/components/containers/footers/footer.tsx
@@ -0,0 +1,32 @@
+import type { ReactNode } from 'react';
+
+import { Flex, styled } from 'leather-styles/jsx';
+
+interface FooterProps {
+ children: ReactNode;
+ variant?: 'page' | 'card';
+ flexDirection?: 'column' | 'row';
+}
+
+export function Footer({ children, variant = 'page', flexDirection = 'column' }: FooterProps) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/app/ui/components/containers/headers/components/network-mode-badge.tsx b/src/app/ui/components/containers/headers/components/network-mode-badge.tsx
new file mode 100644
index 00000000000..a9dfa731c82
--- /dev/null
+++ b/src/app/ui/components/containers/headers/components/network-mode-badge.tsx
@@ -0,0 +1,27 @@
+import { Flex, styled } from 'leather-styles/jsx';
+
+interface NetworkModeBadge {
+ isTestnetChain: boolean;
+ name: string;
+}
+
+export function NetworkModeBadge({ isTestnetChain, name }: NetworkModeBadge) {
+ if (!isTestnetChain) return null;
+
+ // TODO #4794: replace with design system tag
+ return (
+
+
+ {name}
+
+
+ );
+}
diff --git a/src/app/components/drawer/components/header-action-button.tsx b/src/app/ui/components/containers/headers/header-action-button.tsx
similarity index 62%
rename from src/app/components/drawer/components/header-action-button.tsx
rename to src/app/ui/components/containers/headers/header-action-button.tsx
index 3fa5c4308a0..b8672c118cf 100644
--- a/src/app/components/drawer/components/header-action-button.tsx
+++ b/src/app/ui/components/containers/headers/header-action-button.tsx
@@ -1,34 +1,36 @@
import { HomePageSelectors } from '@tests/selectors/home.selectors';
-import { Grid } from 'leather-styles/jsx';
+import { Flex, FlexProps } from 'leather-styles/jsx';
-interface HeaderActionButtonProps {
+interface HeaderActionButtonProps extends FlexProps {
icon?: React.JSX.Element;
isWaitingOnPerformedAction?: boolean;
onAction?(): void;
}
-export function HeaderActionButton(props: HeaderActionButtonProps) {
- const { icon, isWaitingOnPerformedAction, onAction } = props;
-
+export function HeaderActionButton({
+ icon,
+ isWaitingOnPerformedAction,
+ onAction,
+ ...rest
+}: HeaderActionButtonProps) {
return (
-
{icon}
-
+
);
}
diff --git a/src/app/ui/components/containers/headers/header.stories.tsx b/src/app/ui/components/containers/headers/header.stories.tsx
new file mode 100644
index 00000000000..f64a44fd9cb
--- /dev/null
+++ b/src/app/ui/components/containers/headers/header.stories.tsx
@@ -0,0 +1,22 @@
+import type { Meta } from '@storybook/react';
+
+import { Header as Component, HeaderProps } from './header';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Containers/Header',
+ args: {
+ variant: 'home',
+ },
+};
+
+export default meta;
+
+export function Header(args: HeaderProps) {
+ return null} onGoBack={() => null} />;
+}
+
+export function PageHeader(args: HeaderProps) {
+ return null} />;
+}
diff --git a/src/app/ui/components/containers/headers/header.tsx b/src/app/ui/components/containers/headers/header.tsx
new file mode 100644
index 00000000000..92b1a42de7d
--- /dev/null
+++ b/src/app/ui/components/containers/headers/header.tsx
@@ -0,0 +1,86 @@
+import { ReactNode } from 'react';
+
+import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors';
+import { Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx';
+
+import { ArrowLeftIcon, CloseIcon } from '@app/ui/icons';
+
+import { HeaderActionButton } from './header-action-button';
+
+export interface HeaderProps {
+ variant: 'page' | 'home' | 'onboarding' | 'dialog' | 'receive';
+ isWaitingOnPerformedAction?: boolean;
+ onClose?(): void;
+ onGoBack?(): void;
+ title?: ReactNode;
+ account?: ReactNode;
+ totalBalance?: ReactNode;
+ settingsMenu?: ReactNode;
+ networkBadge?: ReactNode;
+ logo?: ReactNode;
+}
+
+export function Header({
+ variant,
+ isWaitingOnPerformedAction,
+ onClose,
+ onGoBack,
+ account,
+ totalBalance,
+ settingsMenu,
+ networkBadge,
+ title,
+ logo,
+}: HeaderProps) {
+ const logoItem = onGoBack || logo || account;
+ return (
+
+
+
+ {logoItem && (
+
+ {variant !== 'home' && onGoBack ? (
+ }
+ isWaitingOnPerformedAction={isWaitingOnPerformedAction}
+ onAction={onGoBack}
+ hideFrom={variant === 'receive' ? 'md' : undefined}
+ />
+ ) : undefined}
+ {account ? account : logo}
+
+ )}
+
+
+ {title && {title} }
+
+
+
+ {networkBadge}
+ {totalBalance}
+ {variant !== 'onboarding' && settingsMenu}
+
+ {onClose && (
+ }
+ isWaitingOnPerformedAction={isWaitingOnPerformedAction}
+ onAction={onClose}
+ hideBelow={variant === 'receive' ? 'md' : undefined}
+ />
+ )}
+
+
+
+
+ );
+}
diff --git a/src/app/ui/components/containers/popup/popup-card.tsx b/src/app/ui/components/containers/popup/popup-card.tsx
new file mode 100644
index 00000000000..5a51fc3513b
--- /dev/null
+++ b/src/app/ui/components/containers/popup/popup-card.tsx
@@ -0,0 +1,21 @@
+import { Stack } from 'leather-styles/jsx';
+
+import { HasChildren } from '@app/common/has-children';
+
+export function PopupCard({ children }: HasChildren) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/ui/components/dowpdown-menu/dropdown-menu-item.layout.tsx b/src/app/ui/components/dropdown-menu/dropdown-menu-item.layout.tsx
similarity index 100%
rename from src/app/ui/components/dowpdown-menu/dropdown-menu-item.layout.tsx
rename to src/app/ui/components/dropdown-menu/dropdown-menu-item.layout.tsx
diff --git a/src/app/ui/components/dowpdown-menu/dropdown-menu.stories.tsx b/src/app/ui/components/dropdown-menu/dropdown-menu.stories.tsx
similarity index 100%
rename from src/app/ui/components/dowpdown-menu/dropdown-menu.stories.tsx
rename to src/app/ui/components/dropdown-menu/dropdown-menu.stories.tsx
diff --git a/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx b/src/app/ui/components/dropdown-menu/dropdown-menu.tsx
similarity index 73%
rename from src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
rename to src/app/ui/components/dropdown-menu/dropdown-menu.tsx
index e53cdf06634..981cab44095 100644
--- a/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
+++ b/src/app/ui/components/dropdown-menu/dropdown-menu.tsx
@@ -26,6 +26,7 @@ const dropdownButtonStyles = css({
userSelect: 'none',
'[data-state=open] &': { bg: 'ink.component-background-pressed' },
});
+
function Button({ children, ...props }: HTMLStyledProps<'div'>) {
return (
@@ -36,9 +37,21 @@ function Button({ children, ...props }: HTMLStyledProps<'div'>) {
);
}
+const dropdownIconButtonStyles = css({
+ _hover: { bg: 'ink.component-background-hover' },
+ _focus: { outline: 'none' },
+ p: 'space.02',
+
+ '&[data-state=open]': { bg: 'ink.component-background-pressed' },
+});
+const IconButton: typeof RadixDropdownMenu.Trigger = forwardRef((props, ref) => (
+
+));
+
const dropdownTriggerStyles = css({
_focus: { outline: 'none' },
});
+
const Trigger: typeof RadixDropdownMenu.Trigger = forwardRef((props, ref) => (
));
@@ -50,14 +63,18 @@ const dropdownContentStyles = css({
borderRadius: 'xs',
boxShadow:
'0px 12px 24px 0px rgba(18, 16, 15, 0.08), 0px 4px 8px 0px rgba(18, 16, 15, 0.08), 0px 0px 2px 0px rgba(18, 16, 15, 0.08)',
- p: 'space.02',
+ p: '0',
willChange: 'transform, opacity',
zIndex: 999,
- _closed: { animation: 'slideDownAndOut 140ms ease-in-out' },
- _open: { animation: 'slideUpAndFade 140ms ease-in-out' },
+ // _closed: { animation: 'slideDownAndOut 140ms ease-in-out' },
+ // _open: { animation: 'slideUpAndFade 140ms ease-in-out'
});
-const Content: typeof RadixDropdownMenu.Content = forwardRef((props, ref) => (
-
+const Content: typeof RadixDropdownMenu.Content = forwardRef(({ className, ...props }, ref) => (
+
));
const dropdownMenuLabelStyles = css({
@@ -92,6 +109,12 @@ const dropdownMenuSeparatorStyles = css({
const Separator: typeof RadixDropdownMenu.Separator = forwardRef((props, ref) => (
));
+const dropdownMenuGroupStyles = css({
+ p: 'space.02',
+});
+const Group: typeof RadixDropdownMenu.Group = forwardRef((props, ref) => (
+
+));
export const DropdownMenu = {
Root: RadixDropdownMenu.Root,
@@ -99,6 +122,11 @@ export const DropdownMenu = {
Portal: RadixDropdownMenu.Portal,
Trigger,
Button,
+ Portal: RadixDropdownMenu.Portal,
+ Group,
+ Trigger,
+ Button,
+ IconButton,
Content,
Label,
Item,
diff --git a/src/app/ui/components/flag/flag.stories.tsx b/src/app/ui/components/flag/flag.stories.tsx
index b1f80906d52..2982ea3af10 100644
--- a/src/app/ui/components/flag/flag.stories.tsx
+++ b/src/app/ui/components/flag/flag.stories.tsx
@@ -18,7 +18,7 @@ const meta: Meta = {
controls: { include: ['align'] },
},
render: ({ children, ...args }) => (
- }>
+ }>
{children}
),
@@ -30,6 +30,6 @@ type Story = StoryObj;
export const Flag: Story = {
args: {
- children: ,
+ children: ,
},
};
diff --git a/src/app/ui/components/item/item.stories.tsx b/src/app/ui/components/item/item.stories.tsx
index 7a118342b18..1790c19e145 100644
--- a/src/app/ui/components/item/item.stories.tsx
+++ b/src/app/ui/components/item/item.stories.tsx
@@ -15,11 +15,11 @@ type Story = StoryObj;
export const Item: Story = {
render: () => (
}
- titleLeft={ }
- captionLeft={ }
- titleRight={ }
- captionRight={ }
+ flagImg={ }
+ titleLeft={ }
+ captionLeft={ }
+ titleRight={ }
+ captionRight={ }
/>
),
};
diff --git a/src/app/ui/components/link/link.stories.tsx b/src/app/ui/components/link/link.stories.tsx
index 8048b8a5091..1baf4cfdf65 100644
--- a/src/app/ui/components/link/link.stories.tsx
+++ b/src/app/ui/components/link/link.stories.tsx
@@ -33,17 +33,3 @@ export const Disabled: Story = {
variant: 'underlined',
},
};
-
-// TODO: Remove invert code
-export const InvertLink: Story = {
- parameters: {
- backgrounds: { default: 'leather-dark-mode' },
- controls: { include: [] },
- },
- args: {
- children: 'Link',
- invert: true,
- size: 'md',
- variant: 'underlined',
- },
-};
diff --git a/src/app/ui/components/link/link.tsx b/src/app/ui/components/link/link.tsx
index 6890f139d90..bcbbd902449 100644
--- a/src/app/ui/components/link/link.tsx
+++ b/src/app/ui/components/link/link.tsx
@@ -9,7 +9,7 @@ type LinkProps = Omit, keyof LinkVariant
LinkVariantProps;
export const Link = forwardRef((props: LinkProps, ref: ForwardedRef) => {
- const { children, disabled, fullWidth, invert, size, variant, ...rest } = props;
+ const { children, disabled, fullWidth, size, invert, variant, ...rest } = props;
return (
+
+
+ );
+}
diff --git a/src/app/components/secret-key/mnemonic-key/mnemonic-word-input.tsx b/src/app/ui/components/secret-key/mnemonic-key/mnemonic-word-input.tsx
similarity index 100%
rename from src/app/components/secret-key/mnemonic-key/mnemonic-word-input.tsx
rename to src/app/ui/components/secret-key/mnemonic-key/mnemonic-word-input.tsx
diff --git a/src/app/components/secret-key/mnemonic-key/utils/error-handling.ts b/src/app/ui/components/secret-key/mnemonic-key/utils/error-handling.ts
similarity index 100%
rename from src/app/components/secret-key/mnemonic-key/utils/error-handling.ts
rename to src/app/ui/components/secret-key/mnemonic-key/utils/error-handling.ts
diff --git a/src/app/components/secret-key/mnemonic-key/utils/validation.ts b/src/app/ui/components/secret-key/mnemonic-key/utils/validation.ts
similarity index 100%
rename from src/app/components/secret-key/mnemonic-key/utils/validation.ts
rename to src/app/ui/components/secret-key/mnemonic-key/utils/validation.ts
diff --git a/src/app/ui/components/secret-key/secret-key-grid.tsx b/src/app/ui/components/secret-key/secret-key-grid.tsx
new file mode 100644
index 00000000000..1082a2b62a6
--- /dev/null
+++ b/src/app/ui/components/secret-key/secret-key-grid.tsx
@@ -0,0 +1,20 @@
+import { Grid } from 'leather-styles/jsx';
+
+interface SecretKeyGridProps {
+ children: React.ReactNode;
+}
+export function SecretKeyGrid({ children }: SecretKeyGridProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/features/secret-key-displayer/components/secret-key-word.tsx b/src/app/ui/components/secret-key/secret-key-word.tsx
similarity index 93%
rename from src/app/features/secret-key-displayer/components/secret-key-word.tsx
rename to src/app/ui/components/secret-key/secret-key-word.tsx
index 1fad76031f1..dca0d2b8f27 100644
--- a/src/app/features/secret-key-displayer/components/secret-key-word.tsx
+++ b/src/app/ui/components/secret-key/secret-key-word.tsx
@@ -12,7 +12,7 @@ export function SecretKeyWord({ word, num }: SecretKeyWordProps) {
width="100%"
gap="space.01"
px="space.03"
- backgroundColor="ink.component-background-default"
+ bg="ink.component-background-default"
borderRadius="xs"
>
diff --git a/src/app/features/secret-key-displayer/secret-key-displayer.layout.tsx b/src/app/ui/components/secret-key/secret-key.layout.tsx
similarity index 63%
rename from src/app/features/secret-key-displayer/secret-key-displayer.layout.tsx
rename to src/app/ui/components/secret-key/secret-key.layout.tsx
index c7b30138e2a..651aa81a822 100644
--- a/src/app/features/secret-key-displayer/secret-key-displayer.layout.tsx
+++ b/src/app/ui/components/secret-key/secret-key.layout.tsx
@@ -2,29 +2,33 @@ import { useState } from 'react';
import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Flex, styled } from 'leather-styles/jsx';
+import { Flex, HStack, Stack, styled } from 'leather-styles/jsx';
import { Button } from '@app/ui/components/button/button';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { EyeIcon } from '@app/ui/icons/eye-icon';
import { EyeSlashIcon } from '@app/ui/icons/eye-slash-icon';
-import { SecretKeyGrid } from '../../components/secret-key/secret-key-grid';
-import { SecretKeyWord } from './components/secret-key-word';
+import { SecretKeyGrid } from './secret-key-grid';
+import { SecretKeyWord } from './secret-key-word';
-interface SecretKeyDisplayerLayoutProps {
+interface SecretKeyLayoutProps {
hasCopied: boolean;
onCopyToClipboard(): void;
secretKeyWords: string[] | undefined;
showTitleAndIllustration: boolean;
onBackedUpSecretKey(): void;
}
-export function SecretKeyDisplayerLayout(props: SecretKeyDisplayerLayoutProps) {
- const { hasCopied, onCopyToClipboard, onBackedUpSecretKey, secretKeyWords } = props;
+export function SecretKeyLayout({
+ hasCopied,
+ onCopyToClipboard,
+ onBackedUpSecretKey,
+ secretKeyWords,
+}: SecretKeyLayoutProps) {
const [showSecretKey, setShowSecretKey] = useState(false);
return (
- <>
+
{secretKeyWords?.map((word, index) => (
))}
-
+
setShowSecretKey(!showSecretKey)}
>
- {showSecretKey ? : }
- {showSecretKey ? 'Hide key' : 'Show key'}
+
+ {showSecretKey ? : }
+
+ {showSecretKey ? 'Hide key' : 'Show key'}
+
+
-
- {!hasCopied ? ' Copy' : 'Copied!'}
+
+
+ {!hasCopied ? ' Copy' : 'Copied!'}
+
I've backed it up
- >
+
);
}
diff --git a/src/app/ui/icons/docs/icons.mdx b/src/app/ui/icons/docs/icons.mdx
index 0cf54de7f4b..4c4154ecb70 100644
--- a/src/app/ui/icons/docs/icons.mdx
+++ b/src/app/ui/icons/docs/icons.mdx
@@ -20,7 +20,7 @@ import { iconsList } from './icons-list';
-
Default 24x24
+
Default 24x24
{iconsList.map(item => {
const IconComponent = Icon[item];
@@ -36,7 +36,7 @@ import { iconsList } from './icons-list';
-
Small 16x16
+
Small 16x16
{iconsList.map(item => {
const IconComponent = Icon[item];
diff --git a/src/app/ui/layout/card/card-content.tsx b/src/app/ui/layout/card/card-content.tsx
new file mode 100644
index 00000000000..76d1e651177
--- /dev/null
+++ b/src/app/ui/layout/card/card-content.tsx
@@ -0,0 +1,22 @@
+import { css } from 'leather-styles/css';
+import { Box } from 'leather-styles/jsx';
+
+import { HasChildren } from '@app/common/has-children';
+
+// Content wrapper used in Dialog + SendCryptoLayout
+export function CardContent({ children }: HasChildren) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/ui/layout/card/card.stories.tsx b/src/app/ui/layout/card/card.stories.tsx
new file mode 100644
index 00000000000..1577cefc000
--- /dev/null
+++ b/src/app/ui/layout/card/card.stories.tsx
@@ -0,0 +1,30 @@
+import type { Meta } from '@storybook/react';
+import { Box } from 'leather-styles/jsx';
+
+import { Button } from '@app/ui/components/button/button';
+
+import { Card as Component } from './card';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Layout/Card',
+};
+
+export default meta;
+
+export function Card() {
+ return (
+ null}>
+ Create new account
+
+ }
+ >
+
+
+ );
+}
diff --git a/src/app/ui/layout/card/card.tsx b/src/app/ui/layout/card/card.tsx
new file mode 100644
index 00000000000..f8c1bcba901
--- /dev/null
+++ b/src/app/ui/layout/card/card.tsx
@@ -0,0 +1,26 @@
+import type { ReactNode } from 'react';
+
+import { Flex, Stack, styled } from 'leather-styles/jsx';
+
+interface CardProps {
+ action?: ReactNode;
+ children: ReactNode;
+ title?: ReactNode;
+ text?: string;
+}
+
+export function Card({ action, children, title, text }: CardProps) {
+ return (
+
+ {(title || text) && (
+
+ {title}
+ {text && {text} }
+ {children}
+
+ )}
+ {!title && children}
+ {action}
+
+ );
+}
diff --git a/src/app/ui/layout/page/page.layout.stories.tsx b/src/app/ui/layout/page/page.layout.stories.tsx
new file mode 100644
index 00000000000..d6a29ae0f11
--- /dev/null
+++ b/src/app/ui/layout/page/page.layout.stories.tsx
@@ -0,0 +1,21 @@
+import type { Meta } from '@storybook/react';
+
+import { Card } from '@app/ui/layout/card/card.stories';
+
+import { Page as Component } from './page.layout';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Layout/Page',
+};
+
+export default meta;
+
+export function Page() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/ui/layout/page/page.layout.tsx b/src/app/ui/layout/page/page.layout.tsx
new file mode 100644
index 00000000000..fb8e16dc99b
--- /dev/null
+++ b/src/app/ui/layout/page/page.layout.tsx
@@ -0,0 +1,24 @@
+import { type ReactNode } from 'react';
+
+import { Box } from 'leather-styles/jsx';
+
+interface PageProps {
+ children: ReactNode;
+ showLogo?: boolean;
+}
+
+export function Page({ children }: PageProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/ui/pages/home.layout.stories.tsx b/src/app/ui/pages/home.layout.stories.tsx
new file mode 100644
index 00000000000..6e7dc8f92bc
--- /dev/null
+++ b/src/app/ui/pages/home.layout.stories.tsx
@@ -0,0 +1,51 @@
+import type { Meta } from '@storybook/react';
+import { Box, Flex, Stack } from 'leather-styles/jsx';
+
+import { RouteUrls } from '@shared/route-urls';
+
+import { ActionButton } from '@app/ui/components/account/action-button';
+import { Tabs } from '@app/ui/components/tabs/tabs';
+import { ArrowDownIcon, ArrowUpIcon, PlusIcon, SwapIcon } from '@app/ui/icons';
+
+import { HomeLayout as Component } from './home.layout';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Pages/Home',
+};
+
+export default meta;
+
+export function HomeLayout() {
+ return (
+
+ } label="Send" />
+ } label="Receive" />
+ } label="Buy" />
+ } label="Swap" />
+
+ }
+ >
+
+
+
+
+ Assets
+
+
+ Activity
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/ui/pages/home.layout.tsx b/src/app/ui/pages/home.layout.tsx
new file mode 100644
index 00000000000..f0b65be2f17
--- /dev/null
+++ b/src/app/ui/pages/home.layout.tsx
@@ -0,0 +1,31 @@
+import type { ReactNode } from 'react';
+
+import { HomePageSelectors } from '@tests/selectors/home.selectors';
+import { Box, Stack } from 'leather-styles/jsx';
+
+interface HomeLayoutProps {
+ children: ReactNode;
+ accountCard: ReactNode;
+}
+
+export function HomeLayout({ children, accountCard }: HomeLayoutProps) {
+ return (
+
+
+ {accountCard}
+
+ {children}
+
+ );
+}
diff --git a/src/app/ui/pages/two-column.layout.stories.tsx b/src/app/ui/pages/two-column.layout.stories.tsx
new file mode 100644
index 00000000000..482571827d5
--- /dev/null
+++ b/src/app/ui/pages/two-column.layout.stories.tsx
@@ -0,0 +1,20 @@
+import type { Meta } from '@storybook/react';
+import { Box } from 'leather-styles/jsx';
+
+import { TwoColumnLayout as Component } from './two-column.layout';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Design System/Layout/TwoColumnLayout',
+};
+
+export default meta;
+
+export function TwoColumnLayout() {
+ return (
+ Hello world>} content={lorem ipsum
} action={<>some action>}>
+
+
+ );
+}
diff --git a/src/app/ui/pages/two-column.layout.tsx b/src/app/ui/pages/two-column.layout.tsx
new file mode 100644
index 00000000000..2dfe8676b29
--- /dev/null
+++ b/src/app/ui/pages/two-column.layout.tsx
@@ -0,0 +1,60 @@
+import { Box, Flex, Stack, styled } from 'leather-styles/jsx';
+
+interface TwoColumnLayoutProps {
+ title: React.JSX.Element;
+ content: React.JSX.Element;
+ action?: React.JSX.Element;
+ children: React.JSX.Element;
+ wideChild?: boolean;
+}
+
+export function TwoColumnLayout({
+ title,
+ content,
+ action,
+ children,
+ wideChild,
+}: TwoColumnLayoutProps): React.JSX.Element {
+ return (
+
+
+
+ {title}
+ {content}
+ {action}
+
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/src/app/ui/pages/welcome.layout.tsx b/src/app/ui/pages/welcome.layout.tsx
new file mode 100644
index 00000000000..6a2679569f0
--- /dev/null
+++ b/src/app/ui/pages/welcome.layout.tsx
@@ -0,0 +1,143 @@
+import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors';
+import { Flex, styled } from 'leather-styles/jsx';
+
+import { useThemeSwitcher } from '@app/common/theme-provider';
+import { Button } from '@app/ui/components/button/button';
+import { Link } from '@app/ui/components/link/link';
+import { LettermarkIcon } from '@app/ui/icons/lettermark-icon';
+import { LogomarkIcon } from '@app/ui/icons/logomark-icon';
+
+interface WelcomeLayoutProps {
+ isGeneratingWallet: boolean;
+ onSelectConnectLedger(): void;
+ onStartOnboarding(): void;
+ onRestoreWallet(): void;
+}
+export function WelcomeLayout({
+ isGeneratingWallet,
+ onStartOnboarding,
+ onSelectConnectLedger,
+ onRestoreWallet,
+}: WelcomeLayoutProps): React.JSX.Element {
+ // On this page 'theme' is used to set specific colours and bypass automatic theming
+ const { theme } = useThemeSwitcher();
+ // hardcoded specific instances of colour variables needed to bypass theme
+ const inkBgSecondary = '#F5F1ED';
+ const inkTextPrimary = '#12100F';
+
+ const primaryActionButton = {
+ p: 'space.03',
+ minWidth: '148px',
+ bg: {
+ base: inkBgSecondary,
+ md: theme === 'light' ? inkBgSecondary : inkTextPrimary,
+ },
+ color: {
+ base: inkTextPrimary,
+ md: theme === 'light' ? inkTextPrimary : inkBgSecondary,
+ },
+
+ _hover: {
+ bg: 'ink.action-primary-hover',
+ color: theme === 'light' ? inkBgSecondary : inkTextPrimary,
+ },
+ };
+ const secondaryActionButton = {
+ p: 'space.03',
+ minWidth: '148px',
+ color: { base: inkBgSecondary, md: theme === 'light' ? inkBgSecondary : inkTextPrimary },
+ border: `1px solid ${inkBgSecondary}`,
+ borderColor: { base: inkBgSecondary, md: theme === 'light' ? inkBgSecondary : inkTextPrimary },
+ _hover: {
+ bg: 'ink.action-primary-hover',
+ color: 'ink.background-secondary',
+ },
+ };
+
+ const tagline = 'Bitcoin for the rest of us';
+ const taglineExtended = 'The bitcoin wallet for the rest of us';
+ const subheader =
+ 'Leather is the only Bitcoin wallet you need to tap into the emerging Bitcoin economy';
+
+ return (
+
+
+
+
+ {tagline}
+
+
+ {taglineExtended}
+
+
+
+ {subheader}
+
+
+
+
+ Create new wallet
+
+
+
+
+ Use existing key
+
+
+ Use Ledger
+
+
+
+
+
+
+
+
+ leather.io
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/ui/utils/prism.tsx b/src/app/ui/utils/prism.tsx
index e4ae2112869..3a69ba152da 100644
--- a/src/app/ui/utils/prism.tsx
+++ b/src/app/ui/utils/prism.tsx
@@ -90,7 +90,7 @@ export type Language =
export const theme: PrismTheme = {
plain: {
color: '#fff',
- backgroundColor: 'transparent',
+ background: 'transparent',
},
styles: [
{
diff --git a/src/background/messaging/messaging-utils.ts b/src/background/messaging/messaging-utils.ts
index c4dfac7bad3..e9422d73f56 100644
--- a/src/background/messaging/messaging-utils.ts
+++ b/src/background/messaging/messaging-utils.ts
@@ -2,7 +2,7 @@ import { InternalMethods } from '@shared/message-types';
import { sendMessage } from '@shared/messages';
import { RouteUrls } from '@shared/route-urls';
-import { popupCenter } from '@background/popup-center';
+import { popup } from '@background/popup';
export function getTabIdFromPort(port: chrome.runtime.Port) {
return port.sender?.tab?.id ?? 0;
@@ -67,5 +67,5 @@ const IS_TEST_ENV = process.env.TEST_ENV === 'true';
export async function triggerRequestWindowOpen(path: RouteUrls, urlParams: URLSearchParams) {
if (IS_TEST_ENV) return openRequestInFullPage(path, urlParams);
- return popupCenter({ url: `/popup-center.html#${path}?${urlParams.toString()}` });
+ return popup({ url: `/popup.html#${path}?${urlParams.toString()}` });
}
diff --git a/src/background/popup-center.ts b/src/background/popup-center.ts
deleted file mode 100644
index 5720a460c6f..00000000000
--- a/src/background/popup-center.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { POPUP_CENTER_HEIGHT, POPUP_CENTER_WIDTH } from '@shared/constants';
-
-interface PopupOptions {
- url?: string;
- title?: string;
- w?: number;
- h?: number;
- skipPopupFallback?: boolean;
-}
-export function popupCenter(options: PopupOptions): Promise {
- const { url, w = POPUP_CENTER_WIDTH, h = POPUP_CENTER_HEIGHT } = options;
-
- return new Promise(resolve => {
- // @see https://developer.chrome.com/docs/extensions/reference/windows/#method-getCurrent
- chrome.windows.getCurrent(async win => {
- // these units take into account the distance from
- // the farthest left/top sides of all displays
- const dualScreenLeft = win.left ?? 0;
- const dualScreenTop = win.top ?? 0;
-
- // dimensions of the window that originated the action
- const width = win.width ?? 0;
- const height = win.height ?? 0;
-
- const left = Math.floor(width / 2 - w / 2 + dualScreenLeft);
- const top = Math.floor(height / 2 - h / 2 + dualScreenTop);
-
- const popup = await chrome.windows.create({
- url,
- width: w,
- height: h,
- top,
- left,
- focused: true,
- type: 'popup',
- });
-
- resolve(popup);
- });
- });
-}
diff --git a/src/background/popup.ts b/src/background/popup.ts
new file mode 100644
index 00000000000..4ab68d7331f
--- /dev/null
+++ b/src/background/popup.ts
@@ -0,0 +1,63 @@
+import { pxStringToNumber } from '@shared/utils/px-string-to-number';
+
+// FIXME import from '@leather-wallet/tokens'
+// import { tokens } from '../../theme/tokens';
+/**
+ * importing from tokens gives TS error about
+ *
+ * You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
+| value: { fontFamily: firaCode, fontSize: '0.6rem', lineHeight: '1rem' },
+| },
+> } as const;
+ */
+
+const tokens = {
+ sizes: {
+ popupWidth: { value: '390px' },
+ popupHeight: { value: '756px' },
+ },
+};
+
+interface PopupOptions {
+ url?: string;
+ title?: string;
+ skipPopupFallback?: boolean;
+}
+
+export function popup(options: PopupOptions): Promise {
+ // TODO 4370 - ask about this
+ // if APP already open in full screen the window opens in a full screen and looks weird
+ const { url } = options;
+
+ const popupWidth = pxStringToNumber(tokens.sizes.popupWidth.value);
+ const popupHeight = pxStringToNumber(tokens.sizes.popupHeight.value);
+
+ return new Promise(resolve => {
+ // @see https://developer.chrome.com/docs/extensions/reference/windows/#method-getCurrent
+ chrome.windows.getCurrent(async win => {
+ // these units take into account the distance from
+ // the farthest left/top sides of all displays
+ const dualScreenLeft = win.left ?? 0;
+ const dualScreenTop = win.top ?? 0;
+
+ // dimensions of the window that originated the action
+ const width = win.width ?? 0;
+ const height = win.height ?? 0;
+
+ const left = Math.floor(width / 2 - popupWidth / 2 + dualScreenLeft);
+ const top = Math.floor(height / 2 - popupHeight / 2 + dualScreenTop);
+
+ const popup = await chrome.windows.create({
+ url,
+ width: popupWidth,
+ height: popupHeight,
+ top,
+ left,
+ focused: true,
+ type: 'popup',
+ });
+
+ resolve(popup);
+ });
+ });
+}
diff --git a/src/shared/constants.ts b/src/shared/constants.ts
index f3138a0868c..b68372997a6 100644
--- a/src/shared/constants.ts
+++ b/src/shared/constants.ts
@@ -4,9 +4,6 @@ import { Blockchains } from './models/blockchain.model';
export const gaiaUrl = 'https://hub.blockstack.org';
-export const POPUP_CENTER_WIDTH = 442;
-export const POPUP_CENTER_HEIGHT = 646;
-
export const HIGH_FEE_AMOUNT_STX = 5;
export const HIGH_FEE_WARNING_LEARN_MORE_URL_BTC = 'https://bitcoinfees.earn.com/';
export const HIGH_FEE_WARNING_LEARN_MORE_URL_STX = 'https://hiro.so/questions/fee-estimates';
diff --git a/src/shared/route-urls.ts b/src/shared/route-urls.ts
index 2ca8451ca83..e58fa2852eb 100644
--- a/src/shared/route-urls.ts
+++ b/src/shared/route-urls.ts
@@ -52,9 +52,9 @@ export enum RouteUrls {
BitcoinContractList = '/bitcoin-contract-list',
// Modal routes
- ChangeTheme = 'change-theme',
+ // ChangeTheme = 'change-theme',
EditNonce = 'edit-nonce',
- SelectNetwork = 'choose-network',
+ // SelectNetwork = 'choose-network',
SignOutConfirm = 'sign-out',
RetrieveTaprootFunds = 'retrieve-taproot-funds',
@@ -65,6 +65,7 @@ export enum RouteUrls {
SendCryptoAssetFormRecipientAccounts = 'recipient-accounts',
SendCryptoAssetFormRecipientBns = 'recipient-bns',
SendBtcChooseFee = '/send/btc/choose-fee',
+ SendBtcError = '/send/btc/error',
SendBtcConfirmation = '/send/btc/confirm',
SendBtcDisabled = '/send/btc/disabled',
SendStxConfirmation = '/send/stx/confirm',
diff --git a/src/shared/utils/px-string-to-number.spec.ts b/src/shared/utils/px-string-to-number.spec.ts
new file mode 100644
index 00000000000..738f80f0276
--- /dev/null
+++ b/src/shared/utils/px-string-to-number.spec.ts
@@ -0,0 +1,12 @@
+import { pxStringToNumber } from './px-string-to-number';
+
+describe('convert px string to number for calculation', () => {
+ it('converts standard px string to number', () => {
+ const result = pxStringToNumber('10px');
+ expect(result).toEqual(10);
+ });
+ it('converts token px string to number', () => {
+ const result = pxStringToNumber('600px');
+ expect(result).toEqual(600);
+ });
+});
diff --git a/src/shared/utils/px-string-to-number.ts b/src/shared/utils/px-string-to-number.ts
new file mode 100644
index 00000000000..f942018d314
--- /dev/null
+++ b/src/shared/utils/px-string-to-number.ts
@@ -0,0 +1,3 @@
+export function pxStringToNumber(pxString: string): number {
+ return +pxString.replace('px', '');
+}
diff --git a/test-app/src/components/app.tsx b/test-app/src/components/app.tsx
index 6fc725e1f05..fa913eb5d87 100755
--- a/test-app/src/components/app.tsx
+++ b/test-app/src/components/app.tsx
@@ -2,9 +2,9 @@ import React from 'react';
import { AppContext } from '@common/context';
import { useAuth } from '@common/use-auth';
-import { Header } from '@components/header';
import { Home } from '@components/home';
import { Connect } from '@stacks/connect-react';
+import { Box, styled } from 'leather-styles/jsx';
import { Flex } from 'leather-styles/jsx';
export const App: React.FC = () => {
@@ -17,7 +17,22 @@ export const App: React.FC = () => {
{/*These are for tests*/}
{authResponse && }
{appPrivateKey && }
-
+
+ {state.userData ? (
+
+ {
+ handleSignOut();
+ }}
+ >
+ Sign out
+
+
+ ) : null}
+
diff --git a/test-app/src/components/bns.tsx b/test-app/src/components/bns.tsx
index 50e30a3065d..21c0c754974 100644
--- a/test-app/src/components/bns.tsx
+++ b/test-app/src/components/bns.tsx
@@ -2,6 +2,8 @@ import React from 'react';
import { Box, styled } from 'leather-styles/jsx';
+/** TODO 4370 - Delete this as the link is broken ???? */
+/** @deprecated */
export const Bns = () => {
return (
diff --git a/test-app/src/components/counter-actions.tsx b/test-app/src/components/counter-actions.tsx
index 50590867e84..94a34fba30e 100644
--- a/test-app/src/components/counter-actions.tsx
+++ b/test-app/src/components/counter-actions.tsx
@@ -5,7 +5,7 @@ import { AppContext } from '@common/context';
import { getRPCClient, stacksTestnetNetwork as network } from '@common/utils';
import { ExplorerLink } from '@components/explorer-link';
import { useConnect } from '@stacks/connect-react';
-import { Box, styled } from 'leather-styles/jsx';
+import { Box, Flex, styled } from 'leather-styles/jsx';
export const CounterActions: React.FC = () => {
const { userData } = React.useContext(AppContext);
@@ -54,26 +54,30 @@ export const CounterActions: React.FC = () => {
return (
- {!userData && Log in to change the state of this smart contract. }
-
- callMethod('increment')}>
+ {!userData && (
+
+ Log in to change the state of this smart contract.
+
+ )}
+
+ callMethod('increment')}>
Increase by 1
-
- callMethod('decrement')}>
+
+ callMethod('decrement')}>
Decrease by 1
-
-
+
+
Get current value
-
-
+
+
{error && (
-
+
{error}
-
+
)}
{txId && !loading && }
{counter !== null && !loading && (
- Current counter value: {counter}
+ Current counter value: {counter}
)}
);
diff --git a/test-app/src/components/header.tsx b/test-app/src/components/header.tsx
deleted file mode 100644
index d98839c4e4f..00000000000
--- a/test-app/src/components/header.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React, { useContext } from 'react';
-
-import { AppContext } from '@common/context';
-import { Link } from '@components/link';
-import { Box, styled } from 'leather-styles/jsx';
-
-interface HeaderProps {
- signOut: () => void;
-}
-
-export const Header: React.FC = ({ signOut }) => {
- const state = useContext(AppContext);
- return (
-
- {state.userData ? (
-
- {
- signOut();
- }}
- >
- Sign out
-
-
- ) : null}
-
- );
-};
diff --git a/tests/page-object-models/home.page.ts b/tests/page-object-models/home.page.ts
index e54b5b11b18..759d07ff0ab 100644
--- a/tests/page-object-models/home.page.ts
+++ b/tests/page-object-models/home.page.ts
@@ -35,7 +35,7 @@ export class HomePage {
constructor(page: Page) {
this.page = page;
- this.drawerActionButton = page.getByTestId(HomePageSelectors.DrawerHeaderActionBtn);
+ this.drawerActionButton = page.getByTestId(HomePageSelectors.HeaderActionBtn);
this.receiveButton = page.getByTestId(HomePageSelectors.ReceiveCryptoAssetBtn);
this.sendButton = page.getByTestId(HomePageSelectors.SendCryptoAssetBtn);
this.swapButton = page.getByTestId(HomePageSelectors.SwapBtn);
@@ -55,7 +55,7 @@ export class HomePage {
this.fundAccountBtn = page.getByTestId(HomePageSelectors.FundAccountBtn);
}
- async goToReceiveModal() {
+ async goToReceiveDialog() {
await this.page.getByTestId(HomePageSelectors.ReceiveCryptoAssetBtn).click();
}
@@ -69,7 +69,7 @@ export class HomePage {
// https://github.com/microsoft/playwright/issues/12168
// Using the `Receive` route to get the account address for now.
async getReceiveNativeSegwitAddress() {
- await this.goToReceiveModal();
+ await this.goToReceiveDialog();
await this.page.getByTestId(HomePageSelectors.ReceiveBtcNativeSegwitQrCodeBtn).click();
const displayerAddress = await this.page
.getByTestId(SharedComponentsSelectors.AddressDisplayer)
@@ -79,14 +79,20 @@ export class HomePage {
// Currently under Ordinals receive flow
async getReceiveTaprootAddress() {
- await this.goToReceiveModal();
+ await this.goToReceiveDialog();
+ await this.page.getByTestId(HomePageSelectors.ReceiveCollectiblesTab).click();
await this.page.getByTestId(HomePageSelectors.ReceiveBtcTaprootQrCodeBtn).click();
- await this.page.getByRole('button', { name: 'Copy address' }).click();
- return this.page.evaluate('navigator.clipboard.readText()');
+ // await this.page.getByRole('button', { name: 'Copy address' }).click();
+ // const address = await this.page.evaluate('navigator.clipboard.readText()');
+ // return address;
+ const displayerAddress = await this.page
+ .getByTestId(SharedComponentsSelectors.AddressDisplayer)
+ .innerText();
+ return displayerAddress.replaceAll('\n', '');
}
async getReceiveStxAddress() {
- await this.goToReceiveModal();
+ await this.goToReceiveDialog();
// In Ledger mode, this element isn't visible, so clicking is conditional
const qrCodeBtn = this.page.getByTestId(HomePageSelectors.ReceiveStxQrCodeBtn);
if (await qrCodeBtn.isVisible()) await qrCodeBtn.click();
diff --git a/tests/page-object-models/onboarding.page.ts b/tests/page-object-models/onboarding.page.ts
index a7260550a61..1c54efe4791 100644
--- a/tests/page-object-models/onboarding.page.ts
+++ b/tests/page-object-models/onboarding.page.ts
@@ -41,7 +41,6 @@ export const testSoftwareAccountDefaultWalletState = {
userSelectedTheme: 'system',
hasAllowedAnalytics: false,
dismissedMessages: [],
- hasApprovedNewBrand: true,
},
_persist: { version: 2, rehydrated: true },
};
diff --git a/tests/page-object-models/send.page.ts b/tests/page-object-models/send.page.ts
index edb0b419c57..9ca91269d74 100644
--- a/tests/page-object-models/send.page.ts
+++ b/tests/page-object-models/send.page.ts
@@ -94,7 +94,7 @@ export class SendPage {
}
async goBack() {
- await this.page.getByTestId(SharedComponentsSelectors.ModalHeaderBackBtn).click();
+ await this.page.getByTestId(SharedComponentsSelectors.HeaderBackBtn).click();
}
async goBackSelectStx() {
diff --git a/tests/selectors/home.selectors.ts b/tests/selectors/home.selectors.ts
index 0b64be33b76..3ef13cea3f3 100644
--- a/tests/selectors/home.selectors.ts
+++ b/tests/selectors/home.selectors.ts
@@ -1,8 +1,10 @@
export enum HomePageSelectors {
- DrawerHeaderActionBtn = 'drawer-header-action-btn',
+ HeaderActionBtn = 'header-action-btn',
HomePageContainer = 'home-page-container',
ReceiveCryptoAssetBtn = 'receive-crypto-asset-btn',
ReceiveBtcNativeSegwitQrCodeBtn = 'receive-native-segwit-qr-code-btn',
+ ReceiveAssetsTab = 'receive-assets-tab',
+ ReceiveCollectiblesTab = 'receive-collectibles-tab',
ReceiveBtcTaprootQrCodeBtn = 'receive-taproot-qr-code-btn',
ReceiveStxQrCodeBtn = 'receive-stx-qr-code-btn',
SendCryptoAssetBtn = 'send-crypto-asset-btn',
diff --git a/tests/selectors/onboarding.selectors.ts b/tests/selectors/onboarding.selectors.ts
index 9371afc424a..fa4e8cb66f7 100644
--- a/tests/selectors/onboarding.selectors.ts
+++ b/tests/selectors/onboarding.selectors.ts
@@ -2,7 +2,7 @@ export enum OnboardingSelectors {
AllowAnalyticsBtn = 'allow-analytics-btn',
BackUpSecretKeyBtn = 'back-up-secret-key-btn',
DenyAnalyticsBtn = 'deny-analytics-btn',
- LeatherLogoRouteToHome = 'leather-logo-route-to-home',
+ LogoRouteToHome = 'logo-route-to-home',
NewPasswordInput = 'set-or-enter-password-input',
NoAssetsFundAccountLink = 'no-assets-fund-account-link',
SecretKey = 'secret-key',
diff --git a/tests/selectors/settings.selectors.ts b/tests/selectors/settings.selectors.ts
index 25d88c0d572..3190412d91e 100644
--- a/tests/selectors/settings.selectors.ts
+++ b/tests/selectors/settings.selectors.ts
@@ -20,7 +20,8 @@ export enum SettingsSelectors {
BtnAddNetwork = 'btn-add-network',
ShowSecretKeyBtn = 'show-secret-key-btn',
GetSupportMenuItem = 'get-support-menu-item',
- SettingsMenuBtn = 'settings-menu-btn',
+ SettingsMenuBtn = 'settings-menu--trigger',
+ SwitchAccountTrigger = 'switch-account-trigger',
SwitchAccountMenuItem = 'switch-account-menu-item',
SwitchAccountItemIndex = 'switch-account-item-[index]',
OpenWalletInNewTab = 'open-wallet-in-new-tab',
diff --git a/tests/selectors/shared-component.selectors.ts b/tests/selectors/shared-component.selectors.ts
index 1090a4c75f1..a35d548cf25 100644
--- a/tests/selectors/shared-component.selectors.ts
+++ b/tests/selectors/shared-component.selectors.ts
@@ -19,9 +19,7 @@ export enum SharedComponentsSelectors {
FeesListItem = 'fee-list-item',
FeesListItemFeeValue = 'fee-list-item-fee-value',
- // Modal Header
- ModalHeaderBackBtn = 'modal-header-back-button',
-
// Error
BroadcastErrorTitle = 'broadcast-error-title',
+ HeaderBackBtn = 'header-back-button',
}
diff --git a/tests/specs/settings/settings-menu.spec.ts b/tests/specs/settings/settings.spec.ts
similarity index 97%
rename from tests/specs/settings/settings-menu.spec.ts
rename to tests/specs/settings/settings.spec.ts
index 48c7bb71d37..92a825fa117 100644
--- a/tests/specs/settings/settings-menu.spec.ts
+++ b/tests/specs/settings/settings.spec.ts
@@ -4,6 +4,7 @@ import { SettingsSelectors } from '@tests/selectors/settings.selectors';
import { test } from '../../fixtures/fixtures';
+// FIXME PETE - this test needs to be updated and improved
test.describe('Settings menu', () => {
test.beforeEach(async ({ extensionId, globalPage, onboardingPage }) => {
await globalPage.setupAndUseApiCalls(extensionId);
diff --git a/theme/global/full-page-styles.ts b/theme/global/full-page-styles.ts
deleted file mode 100644
index e4a41367579..00000000000
--- a/theme/global/full-page-styles.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export const fullPageStyles = {
- '.mode__full-page': {
- '&, body, main, .radix-themes': {
- height: '100%',
- maxHeight: 'unset',
- width: '100%',
- },
- '.main-content': {
- flexGrow: 1,
- justifyContent: 'center',
- margin: '0 auto',
- },
- },
-};
diff --git a/theme/global/global.ts b/theme/global/global.ts
index fdec95e9a18..fca0794f3cc 100644
--- a/theme/global/global.ts
+++ b/theme/global/global.ts
@@ -1,20 +1,24 @@
import { defineGlobalStyles } from '@pandacss/dev';
-import { fullPageStyles } from './full-page-styles';
-import { popupCenterStyles } from './popup-center-styles';
-import { popupStyles } from './popup-styles';
+// TODO import from '@leather-wallet/tokens'
+import { tokens } from '../tokens';
+
+// 4370 TODO audit the use of this file as we are pretty close to not needing it
+// - could set some styles in the