Skip to content

Commit f7090ea

Browse files
feat(extension): autofocus primary action buttons in DappConnector views (#1893)
This aims to improve UX when using only keyboard in DappConnector views
1 parent 496d769 commit f7090ea

File tree

8 files changed

+48
-8
lines changed

8 files changed

+48
-8
lines changed

apps/browser-extension-wallet/src/features/dapp/components/ConfirmData.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export const DappConfirmData = (): React.ReactElement => {
163163
</div>
164164
<div className={styles.actions}>
165165
<Button
166+
autoFocus
166167
onClick={confirmationCallback}
167168
disabled={!formattedData || isConfirmingTx}
168169
data-testid="dapp-transaction-confirm"

apps/browser-extension-wallet/src/features/dapp/components/Connect.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable react/no-multi-comp */
2-
import React, { useEffect, useState } from 'react';
2+
import React, { useEffect, useState, useRef } from 'react';
33
import { Banner, Button, logger } from '@lace/common';
44
import cn from 'classnames';
55
import { useTranslation } from 'react-i18next';
@@ -106,6 +106,14 @@ export const Connect = (): React.ReactElement => {
106106
const [dappInfo, setDappInfo] = useState<Wallet.DappInfo>();
107107
const [isSSLEncrypted, setIsSSLEncrypted] = useState(true);
108108
const { environmentName } = useWalletStore();
109+
const allowAlwaysButtonRef = useRef<HTMLButtonElement>(null);
110+
111+
useEffect(() => {
112+
if (isModalVisible && allowAlwaysButtonRef.current) {
113+
allowAlwaysButtonRef.current.focus();
114+
}
115+
}, [isModalVisible]);
116+
109117
useEffect(() => {
110118
dappDataApi
111119
.getDappInfo()
@@ -151,7 +159,12 @@ export const Connect = (): React.ReactElement => {
151159
<AuthorizeDapp dappInfo={dappInfo} warningBanner={showNonSSLBanner ? <NonSSLBanner /> : <WarningBanner />} />
152160
</div>
153161
<div className={styles.footer}>
154-
<Button className={styles.footerBtn} data-testid="connect-authorize-button" onClick={handleAuthorizeClick}>
162+
<Button
163+
autoFocus
164+
className={styles.footerBtn}
165+
data-testid="connect-authorize-button"
166+
onClick={handleAuthorizeClick}
167+
>
155168
{t('dapp.connect.btn.accept')}
156169
</Button>
157170
<Button
@@ -181,7 +194,12 @@ export const Connect = (): React.ReactElement => {
181194
{t('dapp.connect.modal.description')}
182195
</div>
183196
<div className={styles.modalActions}>
184-
<Button block data-testid="connect-modal-accept-always" onClick={handleAllowAlwaysClick}>
197+
<Button
198+
ref={allowAlwaysButtonRef}
199+
block
200+
data-testid="connect-modal-accept-always"
201+
onClick={handleAllowAlwaysClick}
202+
>
185203
{t('dapp.connect.modal.allowAlways')}
186204
</Button>
187205
<Button block data-testid="connect-modal-accept-once" onClick={handleAllowOnceClick} color="secondary">

apps/browser-extension-wallet/src/features/dapp/components/DappError.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export const DappError = ({
4444
</div>
4545
</div>
4646
<div className={styles.footer}>
47-
<Button data-testid={closeButtonTestId} className={styles.footerBtn} onClick={handleClose}>
47+
<Button autoFocus data-testid={closeButtonTestId} className={styles.footerBtn} onClick={handleClose}>
4848
{closeButtonLabel || t('dapp.dappErrorPage.closeButton')}
4949
</Button>
5050
</div>

apps/browser-extension-wallet/src/features/dapp/components/DappSignDataFail.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const DappSignDataFail = (): React.ReactElement => {
4141
</div>
4242
<div className={styles.footer}>
4343
<Button
44+
autoFocus
4445
data-testid="dapp-sign-data-fail-close-button"
4546
onClick={onClose}
4647
color="secondary"

apps/browser-extension-wallet/src/features/dapp/components/DappSignDataSuccess.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ export const DappSignDataSuccess = (): React.ReactElement => {
3131
</div>
3232
</div>
3333
<div className={styles.footer}>
34-
<Button data-testid="dapp-sign-data-success-close-button" className={styles.footerBtn} onClick={onClose}>
34+
<Button
35+
autoFocus
36+
data-testid="dapp-sign-data-success-close-button"
37+
className={styles.footerBtn}
38+
onClick={onClose}
39+
>
3540
{t('general.button.close')}
3641
</Button>
3742
</div>

apps/browser-extension-wallet/src/features/dapp/components/DappTransactionFail.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const DappTransactionFail = (): React.ReactElement => {
4545
</div>
4646
<div className={styles.footer}>
4747
<Button
48+
autoFocus
4849
data-testid="dapp-sign-tx-fail-close-button"
4950
onClick={onClose}
5051
color="secondary"

apps/browser-extension-wallet/src/features/dapp/components/DappTransactionSuccess.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ export const DappTransactionSuccess = (): React.ReactElement => {
3636
</div>
3737
</div>
3838
<div className={styles.footer}>
39-
<Button data-testid="dapp-sign-tx-success-close-button" className={styles.footerBtn} onClick={onClose}>
39+
<Button
40+
autoFocus
41+
data-testid="dapp-sign-tx-success-close-button"
42+
className={styles.footerBtn}
43+
onClick={onClose}
44+
>
4045
{t('general.button.close')}
4146
</Button>
4247
</div>

apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmTransaction.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useEffect } from 'react';
1+
import React, { useCallback, useEffect, useRef } from 'react';
22
import { Button, logger, PostHogAction } from '@lace/common';
33
import { useTranslation } from 'react-i18next';
44
import { Layout } from '../Layout';
@@ -30,6 +30,7 @@ export const ConfirmTransaction = (): React.ReactElement => {
3030
const analytics = useAnalyticsContext();
3131
const disallowSignTx = useDisallowSignTx(req);
3232
const { isConfirmingTx, signWithHardwareWallet } = useSignWithHardwareWallet(req);
33+
const confirmTransactionButtonRef = useRef<HTMLButtonElement>(null);
3334

3435
const handleConfirmTransaction = () => {
3536
if (!req) return;
@@ -48,6 +49,7 @@ export const ConfirmTransaction = (): React.ReactElement => {
4849
};
4950

5051
const txWitnessRequest = useTxWitnessRequest();
52+
const isConfirmTransactionLoading = !req || (isHardwareWallet && isConfirmingTx);
5153

5254
const cancelTransaction = useCallback(() => {
5355
disallowSignTx(true);
@@ -87,13 +89,20 @@ export const ConfirmTransaction = (): React.ReactElement => {
8789
};
8890
}, [setSignTxRequest, setDappInfo, txWitnessRequest, redirectToDappTxSignFailure, disallowSignTx]);
8991

92+
useEffect(() => {
93+
if (!isConfirmTransactionLoading && confirmTransactionButtonRef.current) {
94+
confirmTransactionButtonRef.current.focus();
95+
}
96+
}, [isConfirmTransactionLoading]);
97+
9098
return (
9199
<Layout pageClassname={styles.spaceBetween}>
92100
{req && walletInfo && inMemoryWallet ? <DappTransactionContainer /> : <Skeleton loading />}
93101
<div className={styles.actions}>
94102
<Button
103+
ref={confirmTransactionButtonRef}
95104
onClick={handleConfirmTransaction}
96-
loading={!req || (isHardwareWallet && isConfirmingTx)}
105+
loading={isConfirmTransactionLoading}
97106
data-testid="dapp-transaction-confirm"
98107
className={styles.actionBtn}
99108
>

0 commit comments

Comments
 (0)