diff --git a/packages/browser-wallet/src/assets/svgX/checkmark.svg b/packages/browser-wallet/src/assets/svgX/checkmark.svg
new file mode 100644
index 000000000..e4db7bbc7
--- /dev/null
+++ b/packages/browser-wallet/src/assets/svgX/checkmark.svg
@@ -0,0 +1,3 @@
+
diff --git a/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.scss b/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.scss
index 610b83a29..9f6052779 100644
--- a/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.scss
+++ b/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.scss
@@ -29,8 +29,25 @@
overflow-wrap: anywhere;
}
+ input.editable {
+ background: none;
+ color: inherit;
+ border: none;
+ font-weight: inherit;
+ font-size: inherit;
+ font-family: inherit;
+ padding: 0;
+ margin: 0;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
.button__icon {
gap: rem(16px);
+ height: rem(16px);
+ width: rem(16px);
.label__main {
color: $color-white;
diff --git a/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.tsx b/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.tsx
index 526d51084..7ad3d8c5f 100644
--- a/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.tsx
+++ b/packages/browser-wallet/src/popup/popupX/pages/Accounts/Accounts.tsx
@@ -1,8 +1,10 @@
-import React from 'react';
+import React, { ChangeEvent, KeyboardEvent, useState } from 'react';
import Plus from '@assets/svgX/plus.svg';
import Arrows from '@assets/svgX/arrows-down-up.svg';
import MagnifyingGlass from '@assets/svgX/magnifying-glass.svg';
import Pencil from '@assets/svgX/pencil-simple.svg';
+import Checkmark from '@assets/svgX/checkmark.svg';
+import Close from '@assets/svgX/close.svg';
import Copy from '@assets/svgX/copy.svg';
import ArrowRight from '@assets/svgX/arrow-right.svg';
import Page from '@popup/popupX/shared/Page';
@@ -16,7 +18,7 @@ import { copyToClipboard } from '@popup/popupX/shared/utils/helpers';
import { useAtomValue } from 'jotai';
import { credentialsAtom } from '@popup/store/account';
import { WalletCredential } from '@shared/storage/types';
-import { useIdentityName } from '@popup/shared/utils/account-helpers';
+import { useIdentityName, useWritableSelectedAccount } from '@popup/shared/utils/account-helpers';
import { useAccountInfo } from '@popup/shared/AccountInfoListenerContext';
import { displayAsCcd } from 'wallet-common-helpers';
@@ -24,6 +26,65 @@ function fallbackAccountName(credentialNumber: number): string {
return `Account ${1 + credentialNumber}`;
}
+type EditableAccountNameProps = {
+ currentName: string;
+ fallbackName: string;
+ onNewName: (newName: string) => void;
+};
+
+function EditableAccountName({ currentName, fallbackName, onNewName }: EditableAccountNameProps) {
+ const [isEditingName, setIsEditingName] = useState(false);
+ const [editedName, setEditedName] = useState(currentName);
+ // Using editedName instead of currentName to avoid flickering after completing.
+ const displayName = editedName === '' ? fallbackName : editedName;
+ const onAbort = () => {
+ setIsEditingName(false);
+ setEditedName(currentName);
+ };
+ const onComplete = () => {
+ onNewName(editedName.trim());
+ setIsEditingName(false);
+ };
+ const onEdit = () => {
+ setEditedName(currentName);
+ setIsEditingName(true);
+ };
+ const onInputChange = (event: ChangeEvent) => {
+ setEditedName(event.target.value);
+ };
+ const onKeyUp = (event: KeyboardEvent) => {
+ if (event.key === 'Enter') {
+ event.preventDefault();
+ onComplete();
+ }
+ };
+ if (isEditingName) {
+ return (
+ <>
+
+
+
+ } onClick={onComplete} />
+ } onClick={onAbort} />
+ >
+ );
+ }
+ return (
+ <>
+ {displayName}
+ } onClick={onEdit} />
+ >
+ );
+}
+
type AccountListItemProps = {
credential: WalletCredential;
};
@@ -34,19 +95,23 @@ function AccountListItem({ credential }: AccountListItemProps) {
const navToPrivateKey = () => nav(absoluteRoutes.settings.accounts.privateKey.path);
const navToConnectedSites = () => nav(absoluteRoutes.settings.accounts.connectedSites.path);
const navToIdCards = () => nav(absoluteRoutes.settings.idCards.path);
-
const identityName = useIdentityName(credential);
const accountInfo = useAccountInfo(credential);
-
- const accountName = credential.credName !== '' ? credential.credName : fallbackAccountName(credential.credNumber);
+ const setAccount = useWritableSelectedAccount(credential.address);
+ const fallbackName = fallbackAccountName(credential.credNumber);
+ const accountName = credential.credName !== '' ? credential.credName : fallbackName;
const { address } = credential;
const ccdBalance =
accountInfo === undefined ? 'Loading' : displayAsCcd(accountInfo.accountAmount.microCcdAmount, false);
+ const onNewAccountName = (newName: string) => setAccount({ credName: newName });
return (
- {accountName}
- } />
+
{address}
diff --git a/packages/browser-wallet/src/popup/shared/utils/account-helpers.ts b/packages/browser-wallet/src/popup/shared/utils/account-helpers.ts
index 18d4e2816..82bb89e83 100644
--- a/packages/browser-wallet/src/popup/shared/utils/account-helpers.ts
+++ b/packages/browser-wallet/src/popup/shared/utils/account-helpers.ts
@@ -51,9 +51,11 @@ export function useIdentityName(credential: WalletCredential, fallback?: string)
export function useWritableSelectedAccount(accountAddress: string) {
const [accounts, setAccounts] = useAtom(writableCredentialAtom);
- const setAccount = (update: WalletCredential) =>
+ const setAccount = (update: Partial) =>
setAccounts(
- accounts.map((account) => (account.address === accountAddress ? { ...account, ...update } : account))
+ accounts.map((account) =>
+ account.address === accountAddress ? ({ ...account, ...update } as WalletCredential) : account
+ )
);
return setAccount;