Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link Control require user to manually submit any changes #50668

Merged
merged 16 commits into from
May 25, 2023

Conversation

getdave
Copy link
Contributor

@getdave getdave commented May 16, 2023

What?

Requires users to manually submit any changes to link "settings" (e.g. Open in new tab .etc) in the Link UI.

⚠️ This means that simply toggling the Opens in new tab will not automatically submit the value.

Closes #50945

Why?

Since the inception of <LinkControl> toggling a setting (e.g. Open in new tab) meant that the Link UI automatically submitted itself. This was intended functionality but the implementation had bugs.

For example when users made a change to the link URL or Text, and then subsequently toggled the Open in new tab, the value would get submitted with the change to the opensInNewTab setting, but without the changes to the URL or Text.

This is not the correct behaviour and often resulted in confusion when changes to the URL of Text were not persisted.

We could have changed this so that toggling the toggle submits the entire value including changes to URL and Text, but that seems strange when we have an Apply button that implies all changes must be manually submitted. Let's lean on that.

This PR changes things so that all changes to settings must be submitted using Apply. Clicking Cancel or otherwise opting out will cause the change to the toggle to be discarded.

This UX expectation is reinforced by only enabling the Apply button when any part of the value has changed.

How?

Rework the tracking of the internal (unsubmitted) values to track the entire value object and not just the url or title fields.

The purpose of the internal state is to track any as yet unsubmitted changes to the link. This is in order to allow users to discard their changes at any point.

Therefore we must check whether the internal state now differs from the original value passed in. We can safely (and quickly thanks to referential equality) do this with the shallow equality utility as the properties of the value are always shallow.

With this in place we can selectively track changes to the intenral link value and only submit when the user is ready. Moreover we can improve the UI to only enable Apply when changes have been made thereby providing an improved UX.

Testing Instructions

Repeat the steps below in the places Link Control is used:

  • Rich Text (e.g. paragraph)
  • Nav block

Steps:

  • Create a link.
  • Check that the Apply button is not enabled unless you make changes to that link value in some way
  • Check particularly that toggling "Open in new tab" doesn't cause the UI to submit/close.

Testing Instructions for Keyboard

Screenshots or screencast

Screen.Capture.on.2023-05-16.at.14-29-54.mp4

@getdave getdave self-assigned this May 16, 2023
Comment on lines 418 to 420
value={ internalControlValue }
settings={ settings }
onChange={ onChange }
onChange={ setInternalSettingValue }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes means that any changes to settings are stored in internal state and not submitted until the user confirms with "Apply".

Comment on lines +429 to +431
disabled={
! valueHasChanges || currentInputIsEmpty
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means the Apply button will not be active until changes to the internal value are detected.

@@ -2236,7 +2287,7 @@ describe( 'Controlling link title text', () => {
).not.toBeInTheDocument();
} );

it( 'should reset state on value change', async () => {
it( 'should reset state upon controlled value change', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change but it helps improve the meaning of the test.

Comment on lines +198 to +199
// Todo: bug if the missing dep is introduced. Will need a fix.
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is unrelated and is caused by the enabling of the relevant eslint rule. Fixing the code to conform causes a bug so I don't want to fix this now.

Comment on lines -219 to +276
if (
currentUrlInputValue !== value?.url ||
internalTextInputValue !== value?.title
) {
if ( valueHasChanges ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of testing for individual properties of the value, this uses a shallow comparison to check if the external (controlled) and internal values are different. If there is a difference then the internal value has changed and thus we need to submit those changes.

@@ -241,8 +298,7 @@ function LinkControl( {
};

const resetInternalValues = () => {
setInternalUrlInputValue( value?.url );
setInternalTextInputValue( value?.title );
setInternalControlValue( value );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of resetting individual properties, "reset" now just means "sync back to whatever value was/is"

name: 'Apply',
} );

expect( submitButton ).toBeDisabled();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there are no changes Submit should be disabled.

Comment on lines +1818 to +1822
await user.click( opensInNewTabToggle );

// Check settings are **not** directly submitted
// which would trigger the onChange handler.
expect( mockOnChange ).not.toHaveBeenCalled();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously changing a setting automatically "submitted" the value (i.e. calls onChange). This asserts that this is no longer the case.

Comment on lines +1826 to +1836
expect( submitButton ).toBeEnabled();

// Submit the changed setting value using the Apply button
await user.click( submitButton );

// Assert the value is updated.
expect( mockOnChange ).toHaveBeenCalledWith(
expect.objectContaining( {
opensInNewTab: true,
} )
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now a user is required to manually submit any changes to the settings.

@github-actions
Copy link

github-actions bot commented May 16, 2023

Size Change: +2.56 kB (0%)

Total Size: 1.41 MB

Filename Size Change
build/a11y/index.min.js 982 B -11 B (-1%)
build/annotations/index.min.js 2.76 kB -18 B (-1%)
build/api-fetch/index.min.js 2.33 kB -8 B (0%)
build/autop/index.min.js 2.14 kB -8 B (0%)
build/blob/index.min.js 472 B -11 B (-2%)
build/block-directory/index.min.js 7.18 kB -25 B (0%)
build/block-directory/style-rtl.css 1.02 kB -34 B (-3%)
build/block-directory/style.css 1.02 kB -35 B (-3%)
build/block-editor/content-rtl.css 4.23 kB +69 B (+2%)
build/block-editor/content.css 4.23 kB +70 B (+2%)
build/block-editor/default-editor-styles-rtl.css 381 B -22 B (-5%)
build/block-editor/default-editor-styles.css 381 B -22 B (-5%)
build/block-editor/index.min.js 200 kB -5.19 kB (-3%)
build/block-editor/style-rtl.css 15.1 kB -247 B (-2%)
build/block-editor/style.css 15.1 kB -248 B (-2%)
build/block-library/blocks/audio/theme-rtl.css 126 B -12 B (-9%)
build/block-library/blocks/audio/theme.css 126 B -12 B (-9%)
build/block-library/blocks/button/editor-rtl.css 584 B -3 B (-1%)
build/block-library/blocks/button/editor.css 582 B -5 B (-1%)
build/block-library/blocks/button/style-rtl.css 624 B -4 B (-1%)
build/block-library/blocks/button/style.css 623 B -4 B (-1%)
build/block-library/blocks/cover/style-rtl.css 1.61 kB -7 B (0%)
build/block-library/blocks/cover/style.css 1.6 kB -8 B (0%)
build/block-library/blocks/embed/theme-rtl.css 126 B -12 B (-9%)
build/block-library/blocks/embed/theme.css 126 B -12 B (-9%)
build/block-library/blocks/file/editor-rtl.css 316 B +16 B (+5%) 🔍
build/block-library/blocks/file/editor.css 316 B +16 B (+5%) 🔍
build/block-library/blocks/file/view.min.js 375 B -4 B (-1%)
build/block-library/blocks/freeform/editor-rtl.css 2.58 kB +140 B (+6%) 🔍
build/block-library/blocks/freeform/editor.css 2.58 kB +141 B (+6%) 🔍
build/block-library/blocks/gallery/editor-rtl.css 947 B -10 B (-1%)
build/block-library/blocks/gallery/editor.css 952 B -10 B (-1%)
build/block-library/blocks/gallery/style-rtl.css 1.53 kB -19 B (-1%)
build/block-library/blocks/gallery/style.css 1.53 kB -19 B (-1%)
build/block-library/blocks/gallery/theme-rtl.css 108 B -14 B (-11%) 👏
build/block-library/blocks/gallery/theme.css 108 B -14 B (-11%) 👏
build/block-library/blocks/html/editor-rtl.css 336 B -4 B (-1%)
build/block-library/blocks/html/editor.css 337 B -4 B (-1%)
build/block-library/blocks/image/style-rtl.css 1.07 kB +422 B (+65%) 🆘
build/block-library/blocks/image/style.css 1.07 kB +419 B (+64%) 🆘
build/block-library/blocks/image/theme-rtl.css 126 B -11 B (-8%)
build/block-library/blocks/image/theme.css 126 B -11 B (-8%)
build/block-library/blocks/navigation-link/editor-rtl.css 712 B -4 B (-1%)
build/block-library/blocks/navigation-link/editor.css 711 B -4 B (-1%)
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B -3 B (-1%)
build/block-library/blocks/navigation-submenu/editor.css 295 B -4 B (-1%)
build/block-library/blocks/navigation/editor-rtl.css 2.33 kB +200 B (+9%) 🔍
build/block-library/blocks/navigation/editor.css 2.33 kB +199 B (+9%) 🔍
build/block-library/blocks/navigation/style-rtl.css 2.21 kB -13 B (-1%)
build/block-library/blocks/navigation/style.css 2.2 kB -10 B (0%)
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB -1 B (0%)
build/block-library/blocks/navigation/view.min.js 443 B -4 B (-1%)
build/block-library/blocks/post-comments-form/style-rtl.css 508 B +7 B (+1%)
build/block-library/blocks/post-comments-form/style.css 508 B +7 B (+1%)
build/block-library/blocks/post-featured-image/style-rtl.css 319 B -3 B (-1%)
build/block-library/blocks/post-featured-image/style.css 319 B -3 B (-1%)
build/block-library/blocks/shortcode/editor-rtl.css 323 B -6 B (-2%)
build/block-library/blocks/shortcode/editor.css 323 B -6 B (-2%)
build/block-library/blocks/site-logo/editor-rtl.css 754 B -6 B (-1%)
build/block-library/blocks/site-logo/editor.css 754 B -6 B (-1%)
build/block-library/blocks/spacer/editor-rtl.css 348 B -11 B (-3%)
build/block-library/blocks/spacer/editor.css 348 B -11 B (-3%)
build/block-library/blocks/table/style-rtl.css 645 B -6 B (-1%)
build/block-library/blocks/table/style.css 644 B -6 B (-1%)
build/block-library/blocks/table/theme-rtl.css 146 B -11 B (-7%)
build/block-library/blocks/table/theme.css 146 B -11 B (-7%)
build/block-library/blocks/video/style-rtl.css 174 B -5 B (-3%)
build/block-library/blocks/video/style.css 174 B -5 B (-3%)
build/block-library/blocks/video/theme-rtl.css 126 B -13 B (-9%)
build/block-library/blocks/video/theme.css 126 B -13 B (-9%)
build/block-library/common-rtl.css 1.1 kB -20 B (-2%)
build/block-library/common.css 1.1 kB -20 B (-2%)
build/block-library/editor-rtl.css 12.1 kB +284 B (+2%)
build/block-library/editor.css 12.1 kB +276 B (+2%)
build/block-library/index.min.js 205 kB -84 B (0%)
build/block-library/interactive-blocks/interactivity.min.js 0 B -2.19 kB (removed) 🏆
build/block-library/interactive-blocks/navigation.min.js 0 B -841 B (removed) 🏆
build/block-library/interactive-blocks/vendors.min.js 0 B -8.15 kB (removed) 🏆
build/block-library/style-rtl.css 13.1 kB +244 B (+2%)
build/block-library/style.css 13.1 kB +256 B (+2%)
build/block-library/theme-rtl.css 686 B -12 B (-2%)
build/block-library/theme.css 691 B -12 B (-2%)
build/block-serialization-default-parser/index.min.js 1.12 kB -8 B (-1%)
build/blocks/index.min.js 50.9 kB -141 B (0%)
build/commands/index.min.js 15 kB +29 B (0%)
build/commands/style-rtl.css 827 B -24 B (-3%)
build/commands/style.css 827 B -22 B (-3%)
build/components/index.min.js 232 kB +21.7 kB (+10%) ⚠️
build/components/style-rtl.css 11.7 kB -93 B (-1%)
build/components/style.css 11.7 kB -93 B (-1%)
build/compose/index.min.js 12.4 kB -8 B (0%)
build/core-commands/index.min.js 1.8 kB -8 B (0%)
build/core-data/index.min.js 16.5 kB -75 B (0%)
build/customize-widgets/index.min.js 12.2 kB -36 B (0%)
build/customize-widgets/style-rtl.css 1.38 kB -26 B (-2%)
build/customize-widgets/style.css 1.38 kB -25 B (-2%)
build/data-controls/index.min.js 708 B -10 B (-1%)
build/data/index.min.js 8.68 kB -51 B (-1%)
build/date/index.min.js 40.5 kB -9 B (0%)
build/deprecated/index.min.js 507 B -11 B (-2%)
build/dom-ready/index.min.js 324 B -12 B (-4%)
build/dom/index.min.js 4.72 kB -39 B (-1%)
build/edit-post/classic-rtl.css 544 B -27 B (-5%)
build/edit-post/classic.css 545 B -26 B (-5%)
build/edit-post/index.min.js 35.3 kB -132 B (0%)
build/edit-post/style-rtl.css 7.76 kB -81 B (-1%)
build/edit-post/style.css 7.75 kB -79 B (-1%)
build/edit-site/index.min.js 64 kB -1.91 kB (-3%)
build/edit-site/style-rtl.css 10.5 kB -65 B (-1%)
build/edit-site/style.css 10.5 kB -54 B (-1%)
build/edit-widgets/index.min.js 17.3 kB -64 B (0%)
build/edit-widgets/style-rtl.css 4.53 kB -50 B (-1%)
build/edit-widgets/style.css 4.53 kB -52 B (-1%)
build/editor/index.min.js 45.8 kB -279 B (-1%)
build/editor/style-rtl.css 3.54 kB -54 B (-2%)
build/editor/style.css 3.53 kB -54 B (-2%)
build/element/index.min.js 4.89 kB -51 B (-1%)
build/escape-html/index.min.js 537 B -11 B (-2%)
build/format-library/index.min.js 7.77 kB -23 B (0%)
build/format-library/style-rtl.css 554 B -23 B (-4%)
build/format-library/style.css 553 B -24 B (-4%)
build/hooks/index.min.js 1.64 kB -28 B (-2%)
build/html-entities/index.min.js 448 B -6 B (-1%)
build/i18n/index.min.js 3.73 kB -20 B (-1%)
build/is-shallow-equal/index.min.js 527 B -8 B (-1%)
build/keyboard-shortcuts/index.min.js 1.78 kB -11 B (-1%)
build/keycodes/index.min.js 1.91 kB -31 B (-2%)
build/list-reusable-blocks/index.min.js 2.14 kB +3 B (0%)
build/list-reusable-blocks/style-rtl.css 836 B -29 B (-3%)
build/list-reusable-blocks/style.css 836 B -29 B (-3%)
build/media-utils/index.min.js 2.97 kB -17 B (-1%)
build/notices/index.min.js 963 B -14 B (-1%)
build/plugins/index.min.js 1.85 kB -13 B (-1%)
build/preferences-persistence/index.min.js 2.22 kB -9 B (0%)
build/preferences/index.min.js 1.33 kB -16 B (-1%)
build/primitives/index.min.js 944 B -16 B (-2%)
build/priority-queue/index.min.js 1.52 kB -2 B (0%)
build/private-apis/index.min.js 939 B -13 B (-1%)
build/react-i18n/index.min.js 696 B -6 B (-1%)
build/react-refresh-entry/index.min.js 8.44 kB -5 B (0%)
build/react-refresh-runtime/index.min.js 7.31 kB +2 B (0%)
build/redux-routine/index.min.js 2.74 kB -10 B (0%)
build/reusable-blocks/index.min.js 2.25 kB -10 B (0%)
build/reusable-blocks/style-rtl.css 243 B -22 B (-8%)
build/reusable-blocks/style.css 243 B -22 B (-8%)
build/rich-text/index.min.js 11 kB -32 B (0%)
build/router/index.min.js 1.78 kB +4 B (0%)
build/server-side-render/index.min.js 2.08 kB -12 B (-1%)
build/shortcode/index.min.js 1.42 kB -6 B (0%)
build/style-engine/index.min.js 1.52 kB -30 B (-2%)
build/token-list/index.min.js 644 B -6 B (-1%)
build/url/index.min.js 3.65 kB -88 B (-2%)
build/viewport/index.min.js 1.08 kB -9 B (-1%)
build/warning/index.min.js 268 B -12 B (-4%)
build/widgets/index.min.js 7.28 kB -15 B (0%)
build/widgets/style-rtl.css 1.15 kB -27 B (-2%)
build/widgets/style.css 1.16 kB -26 B (-2%)
build/wordcount/index.min.js 1.06 kB -2 B (0%)
ℹ️ View Unchanged
Filename Size
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 409 B
build/block-library/blocks/columns/style.css 409 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 159 B
build/block-library/blocks/details/style.css 159 B
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/file/interactivity.min.js 395 B
build/block-library/blocks/file/style-rtl.css 269 B
build/block-library/blocks/file/style.css 270 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 B
build/block-library/blocks/image/interactivity.min.js 783 B
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation/interactivity.min.js 896 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 588 B
build/block-library/blocks/post-featured-image/editor.css 586 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 281 B
build/block-library/blocks/post-template/style.css 281 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 335 B
build/block-library/blocks/pullquote/style.css 335 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 450 B
build/block-library/blocks/query/editor.css 449 B
build/block-library/blocks/quote/style-rtl.css 222 B
build/block-library/blocks/quote/style.css 222 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 178 B
build/block-library/blocks/search/editor.css 178 B
build/block-library/blocks/search/style-rtl.css 434 B
build/block-library/blocks/search/style.css 432 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 403 B
build/block-library/blocks/template-part/editor.css 403 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/interactivity/runtime.min.js 2.68 kB
build/block-library/interactivity/vendors.min.js 8.2 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB

compressed-size-action

@getdave
Copy link
Contributor Author

getdave commented May 16, 2023

Noting that even if we reject the idea that the Opens in new tab needs to be manually submitted, we should still consider merging a subset of the changes in this PR as they improve the reliability of the component.

@draganescu
Copy link
Contributor

Me again with the same question: do we really need "Apply" and "Cancel" on a document that has almost infinite undo, saves itself and is versioned? Isn't the problem that the UI has some lacking in transmitting what happes?

This "cancel or apply" flow makes sense for destructive or complex to undo operations. But for simple toggles it's a bit weird that no other setting from setting intensive UIs such as the inspector require a "commit" action, they just auto commit and hope for the best. E.g. you don't apply increasing padding. You don't apply Bold on a text. It just happens.

But, aside from the complaints above, this PR makes things more unitary from an experience point of view so that's good 👏🏻

@getdave getdave requested a review from richtabor May 17, 2023 09:59
@getdave getdave changed the title [WIP] Internal State fix Link Control require user to manually submit any changes May 24, 2023
@getdave getdave mentioned this pull request May 24, 2023
8 tasks
@getdave getdave added the [Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) label May 24, 2023
@getdave
Copy link
Contributor Author

getdave commented May 25, 2023

@draganescu Thanks for review. Looks like I'm technically heading in the right direciton.

do we really need "Apply" and "Cancel"

I'm going to refer you to the revised UX here. I think any discussion about buttons should continue there 🙇

@getdave getdave marked this pull request as ready for review May 25, 2023 09:17
@getdave getdave requested a review from scruffian May 25, 2023 09:17
@scruffian
Copy link
Contributor

Ideally I think it would be better to change the toggle to a checkbox, but that should definitely be in a different PR.

// Suggestions may contains "settings" values (e.g. `opensInNewTab`)
// which should not overide any existing settings values set by the
// user. This filters out any settings values from the suggestion.
const nonSettingsChanges = Object.keys( updatedValue ).reduce(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a block of code very similar to this above too. Would moving it to the hook mean that we can combine them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't require a hook just a function but yes 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually in future this code won't be necessary so we can ignore it for now and clean up post-refactor if it's still around.

Copy link
Contributor

@scruffian scruffian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works as expected and is an improvement on the current experience. I left a few comments on how we could refactor the code, but nothing that should stop this from being merged.

@getdave
Copy link
Contributor Author

getdave commented May 25, 2023

Ideally I think it would be better to change the toggle to a checkbox, but that should definitely be in a different PR.

I agree. It's going to be done in #50947

@github-actions
Copy link

Flaky tests detected in 3e6f682.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5079002929
📝 Reported issues:

@getdave getdave merged commit 2b687d0 into trunk May 25, 2023
@getdave getdave deleted the fix/link-control-internal-state-tracking branch May 25, 2023 12:16
@github-actions github-actions bot added this to the Gutenberg 16.0 milestone May 25, 2023
Comment on lines +9 to +18
// If the value prop changes, update the internal state.
useEffect( () => {
setInternalValue( ( prevValue ) => {
if ( value && value !== prevValue ) {
return value;
}

return prevValue;
} );
}, [ value ] );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if this sync hook is still needed? Now that value is an object; the synchronization can cause the content loss.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we originally introduced the pattern to fix an issue whereby programmatically updating value didn't update the UI.

@Mamaduka The example is codified in one of the unit tests. Basically if you create x2 separate and different links in a paragraph block and then click between them the UI will reflect the value of that link. Previous to this sync you would continue to see the previous link's value in the UI even if you clicked on another link.

You won't be able to replicate any more because we implemented another fix which passes a key prop to the LinkControl in rich text to force a unique component instance per link instance.

I think we could look to remove the sync. Perhaps a PoC PR is a good place to start. I'll spin up. I've never liked this code and I agree is prone to error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Dave. Let’s continue discussion in the new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changes to Link Control are only saved when using the "Save" button (for all fields).
6 participants