From d142cb0e72cedb369df918caa89513074bda9904 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 7 Feb 2023 09:57:02 +0000 Subject: [PATCH] Add settings "drawer" to Link Control (#47328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add basic panel toggle * Implement drawer like effect * Implement basic animation * Update to have drawer below button * Update timing to 0.2s * Fix janky animation * Close settings drawer when editing is stopped * Fix input overflowing in settings drawer * Disable animations when user requests reduced motion * Force no animations in component tests * Fix text input tests broken due to move into settings drawer * Fix remaining tests broken by settings drawer * speed up animation * Move drawer to dedicated component * Add test for settings drawer with unique ID * Check for aria expanded attribute * Avoid extra div when reduced motion is active * Don’t show settings unless in edit mode * Add test for link settings toggle not being displayed unless editing * Fix e2e tests due to change of text input location * Fix more e2e tests * Fix final e2e test * Fix e2e test that arrived following rebase --------- Co-authored-by: scruffian --- .../src/components/link-control/index.js | 44 +++---- .../link-control/settings-drawer.js | 115 +++++++++++++----- .../src/components/link-control/settings.js | 41 +++++++ .../src/components/link-control/style.scss | 40 ++++-- .../src/components/link-control/test/index.js | 96 ++++++++++++++- .../specs/editor/various/links.test.js | 66 +++++++--- 6 files changed, 326 insertions(+), 76 deletions(-) create mode 100644 packages/block-editor/src/components/link-control/settings.js diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 73e2f6bb8e0e1d..a63723e463d813 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button, Spinner, Notice, TextControl } from '@wordpress/components'; +import { Button, Spinner, Notice } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useRef, useState, useEffect } from '@wordpress/element'; import { focus } from '@wordpress/dom'; @@ -136,6 +136,8 @@ function LinkControl( { const textInputRef = useRef(); const isEndingEditWithFocus = useRef( false ); + const [ settingsOpen, setSettingsOpen ] = useState( false ); + const [ internalUrlInputValue, setInternalUrlInputValue ] = useInternalInputValue( value?.url || '' ); @@ -201,6 +203,7 @@ function LinkControl( { wrapperNode.current.ownerDocument.activeElement ); + setSettingsOpen( false ); setIsEditingLink( false ); }; @@ -267,7 +270,7 @@ function LinkControl( { const shownUnlinkControl = onRemove && value && ! isEditingLink && ! isCreatingPage; - const showSettingsDrawer = !! settings?.length; + const showSettings = !! settings?.length; // Only show text control once a URL value has been committed // and it isn't just empty whitespace. @@ -275,6 +278,7 @@ function LinkControl( { const showTextControl = hasLinkValue && hasTextControl; const isEditing = ( isEditingLink || ! value ) && ! isCreatingPage; + return (
- { showTextControl && ( - - ) } - ) } -
- { showSettingsDrawer && ( -
+ { isEditing && ( +
+ { ( showSettings || showTextControl ) && ( -
- ) } + ) } - { isEditing && (
- ) } -
+
+ ) } { renderControlBottom && renderControlBottom() }
diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js index 4b9d0d7f7419e7..e58b4409645b33 100644 --- a/packages/block-editor/src/components/link-control/settings-drawer.js +++ b/packages/block-editor/src/components/link-control/settings-drawer.js @@ -1,41 +1,96 @@ /** * WordPress dependencies */ +import { + Button, + TextControl, + __unstableMotion as motion, + __unstableAnimatePresence as AnimatePresence, +} from '@wordpress/components'; +import { settings as settingsIcon } from '@wordpress/icons'; +import { useReducedMotion, useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; -import { ToggleControl, VisuallyHidden } from '@wordpress/components'; - -const noop = () => {}; +import { Fragment } from '@wordpress/element'; +/** + * Internal dependencies + */ +import Settings from './settings'; -const LinkControlSettingsDrawer = ( { value, onChange = noop, settings } ) => { - if ( ! settings || ! settings.length ) { - return null; - } +function LinkSettingsDrawer( { + settingsOpen, + setSettingsOpen, + showTextControl, + showSettings, + textInputRef, + internalTextInputValue, + setInternalTextInputValue, + handleSubmitWithEnter, + value, + settings, + onChange, +} ) { + const prefersReducedMotion = useReducedMotion(); + const MaybeAnimatePresence = prefersReducedMotion + ? Fragment + : AnimatePresence; + const MaybeMotionDiv = prefersReducedMotion ? 'div' : motion.div; - const handleSettingChange = ( setting ) => ( newValue ) => { - onChange( { - ...value, - [ setting.id ]: newValue, - } ); - }; + const id = useInstanceId( LinkSettingsDrawer ); - const theSettings = settings.map( ( setting ) => ( - - ) ); + const settingsDrawerId = `link-control-settings-drawer-${ id }`; return ( -
- - { __( 'Currently selected link settings' ) } - - { theSettings } -
+ <> +