)
} ) }
diff --git a/settings/src/components/numeric-control.js b/settings/src/components/numeric-control.js
new file mode 100644
index 00000000..f3ae2c89
--- /dev/null
+++ b/settings/src/components/numeric-control.js
@@ -0,0 +1,29 @@
+/**
+ * Input field for values that use digits, but aren't strictly numbers in the mathematical sense.
+ *
+ * The classic example is a credit card, but in our context we have TOTP codes, backup codes, etc. We may want to
+ * display them with spaces for easier reading, etc.
+ *
+ * If we used Gutenberg's `NumberControl`, we'd have to hide the extraneous UI elements, and it would still be
+ * using the underlying `input[type="number"]`, which has some accessibility issues.
+ *
+ * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#accessibility
+ * @link https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/
+ * @link https://stackoverflow.com/a/66759105/450127
+ */
+export default function NumericControl( props ) {
+ return (
+ {
+ // Most callers will only need the value, so make it convenient for them.
+ props.onChange( event.target.value, event );
+ } }
+ />
+ );
+}
diff --git a/settings/src/components/totp.js b/settings/src/components/totp.js
index 048a8cba..fc87e4c5 100644
--- a/settings/src/components/totp.js
+++ b/settings/src/components/totp.js
@@ -2,15 +2,16 @@
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';
-import { Button, Notice, __experimentalNumberControl as NumberControl } from '@wordpress/components';
+import { Button, Notice } from '@wordpress/components';
import { Icon, cancelCircleFilled } from '@wordpress/icons';
import { RawHTML, useCallback, useContext, useEffect, useState } from '@wordpress/element';
/**
* Internal dependencies
*/
-import SetupProgressBar from './setup-progress-bar';
-import ScreenLink from './screen-link'
+import SetupProgressBar from './setup-progress-bar';
+import ScreenLink from './screen-link'
+import NumericControl from './numeric-control';
import { refreshRecord } from '../utilities';
import { GlobalContext } from '../script';
@@ -197,28 +198,18 @@ function createQrCode( data ) {
*/
function SetupForm( { handleEnable, verifyCode, setVerifyCode, qrCodeUrl, secretKey } ) {
const verifyCodeLength = 6;
- const canSubmit = qrCodeUrl && secretKey && verifyCode && verifyCode.length === verifyCodeLength;
+ const cleanVerifyCode = verifyCode.replaceAll( /\s/g, '' );
+ const canSubmit = qrCodeUrl && secretKey && cleanVerifyCode.length === verifyCodeLength;
return (