@@ -697,6 +721,7 @@ function CardForm({
value={cardExpiration}
onValueChange={handleCardExpirationChange}
onBlur={handleCardExpirationBlur}
+ onEnter={handleInputEnterKey}
/>
{cardExpirationError && (
@@ -720,6 +745,7 @@ function CardForm({
onValueChange={handleCardCvcChange}
maxInputLength={cardFormSettings.cardCvc.maxInputLength}
onBlur={handleCardCvcBlur}
+ onEnter={handleInputEnterKey}
/>
{cardCvcError && (
diff --git a/ts/components/PreferencesDonations.tsx b/ts/components/PreferencesDonations.tsx
index 2be612e7a8..c73a7f821d 100644
--- a/ts/components/PreferencesDonations.tsx
+++ b/ts/components/PreferencesDonations.tsx
@@ -597,7 +597,7 @@ export function PreferencesDonations({
);
useEffect(() => {
- if (!workflow || lastError) {
+ if (lastError) {
setIsSubmitted(false);
}
@@ -636,6 +636,7 @@ export function PreferencesDonations({
errorType={lastError}
i18n={i18n}
onClose={() => {
+ setIsSubmitted(false);
updateLastError(undefined);
}}
/>
diff --git a/ts/components/preferences/donations/DonateInputCardCvc.stories.tsx b/ts/components/preferences/donations/DonateInputCardCvc.stories.tsx
index 3a257f247f..2edad804e6 100644
--- a/ts/components/preferences/donations/DonateInputCardCvc.stories.tsx
+++ b/ts/components/preferences/donations/DonateInputCardCvc.stories.tsx
@@ -14,6 +14,7 @@ export default {
onValueChange: action('onValueChange'),
maxInputLength: 3,
onBlur: action('onBlur'),
+ onEnter: action('onEnter'),
},
} satisfies ComponentMeta;
diff --git a/ts/components/preferences/donations/DonateInputCardCvc.tsx b/ts/components/preferences/donations/DonateInputCardCvc.tsx
index 42cae888c8..c6a0d061e8 100644
--- a/ts/components/preferences/donations/DonateInputCardCvc.tsx
+++ b/ts/components/preferences/donations/DonateInputCardCvc.tsx
@@ -1,6 +1,6 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-import type { FormEvent } from 'react';
+import type { FormEvent, KeyboardEvent } from 'react';
import React, { memo, useCallback, useRef } from 'react';
import { CC_CVC_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
import type { LocalizerType } from '../../../types/I18N';
@@ -30,12 +30,13 @@ export type DonateInputCardCvcProps = Readonly<{
onValueChange: (newValue: string) => void;
maxInputLength: number;
onBlur?: () => void;
+ onEnter?: () => void;
}>;
export const DonateInputCardCvc = memo(function DonateInputCardCvc(
props: DonateInputCardCvcProps
) {
- const { onValueChange } = props;
+ const { onEnter, onValueChange } = props;
const inputRef = useRef(null);
useInputMask(inputRef, CC_CVC_FORMATTER);
@@ -47,6 +48,15 @@ export const DonateInputCardCvc = memo(function DonateInputCardCvc(
[onValueChange]
);
+ const handleKeyDown = useCallback(
+ (event: KeyboardEvent) => {
+ if (onEnter && event.key === 'Enter') {
+ onEnter();
+ }
+ },
+ [onEnter]
+ );
+
return (
);
});
diff --git a/ts/components/preferences/donations/DonateInputCardExp.stories.tsx b/ts/components/preferences/donations/DonateInputCardExp.stories.tsx
index 42b9627331..f66802ec38 100644
--- a/ts/components/preferences/donations/DonateInputCardExp.stories.tsx
+++ b/ts/components/preferences/donations/DonateInputCardExp.stories.tsx
@@ -13,6 +13,7 @@ export default {
value: '',
onValueChange: action('onValueChange'),
onBlur: action('onBlur'),
+ onEnter: action('onEnter'),
},
} satisfies ComponentMeta;
diff --git a/ts/components/preferences/donations/DonateInputCardExp.tsx b/ts/components/preferences/donations/DonateInputCardExp.tsx
index ef6deb8aff..c582a480cb 100644
--- a/ts/components/preferences/donations/DonateInputCardExp.tsx
+++ b/ts/components/preferences/donations/DonateInputCardExp.tsx
@@ -1,6 +1,6 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-import type { FormEvent } from 'react';
+import type { FormEvent, KeyboardEvent } from 'react';
import React, { memo, useCallback, useRef } from 'react';
import { CC_EXP_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
import { CardExpirationError } from '../../../types/DonationsCardForm';
@@ -40,12 +40,13 @@ export type DonateInputCardExpProps = Readonly<{
value: string;
onValueChange: (newValue: string) => void;
onBlur?: () => void;
+ onEnter?: () => void;
}>;
export const DonateInputCardExp = memo(function DonateInputCardExp(
props: DonateInputCardExpProps
) {
- const { onValueChange } = props;
+ const { onEnter, onValueChange } = props;
const inputRef = useRef(null);
useInputMask(inputRef, CC_EXP_FORMATTER);
@@ -57,6 +58,15 @@ export const DonateInputCardExp = memo(function DonateInputCardExp(
[onValueChange]
);
+ const handleKeyDown = useCallback(
+ (event: KeyboardEvent) => {
+ if (onEnter && event.key === 'Enter') {
+ onEnter();
+ }
+ },
+ [onEnter]
+ );
+
return (
);
});
diff --git a/ts/components/preferences/donations/DonateInputCardNumber.stories.tsx b/ts/components/preferences/donations/DonateInputCardNumber.stories.tsx
index 4c4aa04284..ff98d48534 100644
--- a/ts/components/preferences/donations/DonateInputCardNumber.stories.tsx
+++ b/ts/components/preferences/donations/DonateInputCardNumber.stories.tsx
@@ -13,6 +13,7 @@ export default {
value: '',
onValueChange: action('onValueChange'),
onBlur: action('onBlur'),
+ onEnter: action('onEnter'),
maxInputLength: 19,
},
} satisfies ComponentMeta;
diff --git a/ts/components/preferences/donations/DonateInputCardNumber.tsx b/ts/components/preferences/donations/DonateInputCardNumber.tsx
index 06f6a72757..31b61e6075 100644
--- a/ts/components/preferences/donations/DonateInputCardNumber.tsx
+++ b/ts/components/preferences/donations/DonateInputCardNumber.tsx
@@ -1,6 +1,6 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-import type { FormEvent } from 'react';
+import type { FormEvent, KeyboardEvent } from 'react';
import React, { memo, useCallback, useRef } from 'react';
import { CC_NUMBER_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
import type { LocalizerType } from '../../../types/I18N';
@@ -28,12 +28,13 @@ export type DonateInputCardNumberProps = Readonly<{
onValueChange: (newValue: string) => void;
maxInputLength: number;
onBlur?: () => void;
+ onEnter?: () => void;
}>;
export const DonateInputCardNumber = memo(function DonateInputCardNumber(
props: DonateInputCardNumberProps
) {
- const { onValueChange } = props;
+ const { onEnter, onValueChange } = props;
const inputRef = useRef(null);
useInputMask(inputRef, CC_NUMBER_FORMATTER);
@@ -45,6 +46,15 @@ export const DonateInputCardNumber = memo(function DonateInputCardNumber(
[onValueChange]
);
+ const handleKeyDown = useCallback(
+ (event: KeyboardEvent) => {
+ if (onEnter && event.key === 'Enter') {
+ onEnter();
+ }
+ },
+ [onEnter]
+ );
+
return (
);
});