44 * SPDX-License-Identifier: BSD-3-Clause
55 * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66 */
7- import React from 'react'
7+ import React , { useRef , useEffect } from 'react'
88import PropTypes from 'prop-types'
99import {
1010 Box ,
@@ -27,6 +27,9 @@ const SubscribeForm = ({subscription, ...otherProps}) => {
2727 // Use SubscribeForm's own theme config instead of Footer's context
2828 const subscribeFormStyles = useMultiStyleConfig ( 'SubscribeForm' )
2929
30+ // Ref to manage focus on the email input
31+ const emailInputRef = useRef ( null )
32+
3033 // Map SubscribeForm theme parts to Footer's expected structure
3134 const styles = {
3235 subscribe : subscribeFormStyles . container ,
@@ -48,6 +51,19 @@ const SubscribeForm = ({subscription, ...otherProps}) => {
4851 const intl = useIntl ( )
4952 const { state, actions} = subscription
5053
54+ // Restore focus to the email input after submission completes (success or error)
55+ // Track previous loading state to detect when submission completes
56+ const prevLoadingRef = useRef ( false )
57+
58+ useEffect ( ( ) => {
59+ // Only restore focus when transitioning from loading to not loading
60+ // This ensures we only focus after a submission completes, not on mount
61+ if ( prevLoadingRef . current && ! state ?. isLoading && emailInputRef . current ) {
62+ emailInputRef . current . focus ( )
63+ }
64+ prevLoadingRef . current = state ?. isLoading
65+ } , [ state ?. isLoading ] )
66+
5167 const messages = {
5268 heading : intl . formatMessage ( {
5369 id : 'footer.subscribe.heading.stay_updated' ,
@@ -87,21 +103,8 @@ const SubscribeForm = ({subscription, ...otherProps}) => {
87103
88104 < Box >
89105 < InputGroup >
90- { /* Had to swap the following InputRightElement and Input
91- to avoid the hydration error due to mismatched html between server and client side.
92- This is a workaround for Lastpass plugin that automatically injects its icon for input fields.
93- */ }
94- < InputRightElement { ...styles . subscribeButtonContainer } >
95- < Button
96- variant = "footer"
97- onClick = { actions ?. submit }
98- isLoading = { state ?. isLoading }
99- loadingText = { messages . buttonSignUp }
100- >
101- { messages . buttonSignUp }
102- </ Button >
103- </ InputRightElement >
104106 < Input
107+ ref = { emailInputRef }
105108 type = "email"
106109 placeholder = { messages . emailPlaceholder }
107110 aria-label = { messages . emailAriaLabel }
@@ -116,6 +119,16 @@ const SubscribeForm = ({subscription, ...otherProps}) => {
116119 id = "subscribe-email"
117120 { ...styles . subscribeField }
118121 />
122+ < InputRightElement { ...styles . subscribeButtonContainer } >
123+ < Button
124+ variant = "footer"
125+ onClick = { actions ?. submit }
126+ isLoading = { state ?. isLoading }
127+ loadingText = { messages . buttonSignUp }
128+ >
129+ { messages . buttonSignUp }
130+ </ Button >
131+ </ InputRightElement >
119132 </ InputGroup >
120133
121134 < Text { ...styles . subscribeDisclaimer } >
0 commit comments