From c61aa8c908a6b0ad2fc7c81c39c8cf88c5c9a823 Mon Sep 17 00:00:00 2001 From: Ian Dunn Date: Tue, 14 Feb 2023 12:38:26 -0800 Subject: [PATCH 1/2] Add spaces to 2FA codes for readablility. This replace Gutenberg's `NumberControl` with a new `NumericControl`, because the former will not allow spaces. --- settings/src/components/backup-codes.js | 4 +-- settings/src/components/numeric-control.js | 28 +++++++++++++++++++++ settings/src/components/totp.js | 29 ++++++++-------------- settings/src/components/totp.scss | 2 +- settings/src/style.scss | 4 +++ 5 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 settings/src/components/numeric-control.js diff --git a/settings/src/components/backup-codes.js b/settings/src/components/backup-codes.js index af6e01e8..b39dff33 100644 --- a/settings/src/components/backup-codes.js +++ b/settings/src/components/backup-codes.js @@ -123,8 +123,8 @@ function CodeList( { codes } ) {
    { codes.map( ( code ) => { return ( -
  1. - { code } +
  2. + { code.slice( 0, 4 ) + ' ' + code.slice( 4 ) }
  3. ) } ) } diff --git a/settings/src/components/numeric-control.js b/settings/src/components/numeric-control.js new file mode 100644 index 00000000..ab2193de --- /dev/null +++ b/settings/src/components/numeric-control.js @@ -0,0 +1,28 @@ +/** + * 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 (
    - setVerifyCode( code.toString() ) + ( code ) => setVerifyCode( code ) } - hideHTMLArrows={ false } - spinControls="none" required={ true } /> diff --git a/settings/src/components/totp.scss b/settings/src/components/totp.scss index a93e0ddb..106eb870 100644 --- a/settings/src/components/totp.scss +++ b/settings/src/components/totp.scss @@ -21,7 +21,7 @@ } .wporg-2fa__verify-code { - width: 10ch; + width: 13ch; margin-bottom: 20px; } diff --git a/settings/src/style.scss b/settings/src/style.scss index 274edc98..78e90bf9 100644 --- a/settings/src/style.scss +++ b/settings/src/style.scss @@ -37,6 +37,10 @@ } } +.wporg-2fa__token { + letter-spacing: .3em; +} + .components-notice { margin-left: 0; margin-right: 0; From fd77cf3bebd770e05cbe6e2eecd9aa2e0cfb0bf1 Mon Sep 17 00:00:00 2001 From: Ian Dunn Date: Fri, 10 Mar 2023 10:52:46 -0800 Subject: [PATCH 2/2] add pattern title and refine styles --- settings/src/components/numeric-control.js | 1 + settings/src/components/totp.scss | 4 ++-- settings/src/style.scss | 13 +++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/settings/src/components/numeric-control.js b/settings/src/components/numeric-control.js index ab2193de..f3ae2c89 100644 --- a/settings/src/components/numeric-control.js +++ b/settings/src/components/numeric-control.js @@ -19,6 +19,7 @@ export default function NumericControl( props ) { inputMode="numeric" autoComplete={ props.autoComplete || 'off' } pattern={ props.pattern || "[0-9 ]*" } + title={ props.title || "Only numbers and spaces are allowed" } onChange={ ( event ) => { // 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.scss b/settings/src/components/totp.scss index 106eb870..3a361f2f 100644 --- a/settings/src/components/totp.scss +++ b/settings/src/components/totp.scss @@ -4,7 +4,7 @@ #bbpress-forums & { > a { display: inline-block; - + &:hover, &:focus { box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#007cba)); @@ -21,7 +21,7 @@ } .wporg-2fa__verify-code { - width: 13ch; + width: 23ch; margin-bottom: 20px; } diff --git a/settings/src/style.scss b/settings/src/style.scss index 78e90bf9..4af9cc64 100644 --- a/settings/src/style.scss +++ b/settings/src/style.scss @@ -8,6 +8,19 @@ clear: none; } + /* Restore wporg-support styles that bbPress overrides */ + .bbp-single-user & { + input[type="text"], + input[type="email"], + input[type="search"], + input[type="password"], + input[type="number"] { + padding: 6px 10px; + font-size: 14px; + font-family: "Open Sans", sans-serif; + } + } + .components-button { margin-right: 20px; }