diff --git a/core/modules/media_library/css/media_library.theme.css b/core/modules/media_library/css/media_library.theme.css index 9f955197da..d5796bb88b 100644 --- a/core/modules/media_library/css/media_library.theme.css +++ b/core/modules/media_library/css/media_library.theme.css @@ -99,6 +99,10 @@ margin: 0 0 1em; } +.media-library-add-form-media { + outline: none; +} + /* Style the media add upload form. */ .media-library-add-form--upload.media-library-add-form--without-input .form-item-upload { margin-bottom: 0; @@ -108,6 +112,10 @@ margin: 8px 0 0; } +.media-library-add-form-description { + margin: 0; +} + /* Style the media add oEmbed form. */ .media-library-add-form--oembed .media-library-add-form-input-wrapper { display: flex; diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php index 1562c28da8..3658aacb3b 100644 --- a/core/modules/media_library/src/Form/AddFormBase.php +++ b/core/modules/media_library/src/Form/AddFormBase.php @@ -112,7 +112,7 @@ protected function getMediaType(FormStateInterface $form_state) { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['#prefix'] = '
'; + $form['#prefix'] = '
'; $form['#suffix'] = '
'; $form['#attached']['library'][] = 'media_library/style'; @@ -134,6 +134,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['media'] = [ '#type' => 'container', + '#attributes' => [ + 'class' => [ + 'media-library-add-form-media', + ], + 'tabindex' => -1, + 'aria-label' => $this->t('Added media items'), + ], ]; foreach ($added_media as $delta => $media) { @@ -400,7 +407,6 @@ public function updateFormCallback(array &$form, FormStateInterface $form_state) $response = new AjaxResponse(); - // Move focus to the first tabbable element of the add form. // When the source field input contains errors, replace the existing form to // let the user change the source field input. If the user input is valid, // the entire modal is replaced with the second step of the form to show the @@ -410,17 +416,24 @@ public function updateFormCallback(array &$form, FormStateInterface $form_state) return $response; } - // When the list of added media is empty, return to the media library. + // When the list of added media is empty, return to the media library and + // shift focus back to the first tabbable element (which should be the + // source field). if (empty($added_media)) { $response->addCommand(new ReplaceCommand('#media-library-add-form-wrapper', $this->buildMediaLibraryUi())); + $response->addCommand(new InvokeCommand('#media-library-add-form-wrapper :tabbable', 'focus')); + } + // When the remove button is clicked and there are still more items, the + // AJAX system automatically sets focus to the next remove button. + elseif (end($triggering_element['#parents']) === 'remove_button') { + $response->addCommand(new ReplaceCommand("#$wrapper_id", $form)); } - // Return the form. + // Update the form and shift focus to the added media items. else { $response->addCommand(new ReplaceCommand("#$wrapper_id", $form)); + $response->addCommand(new InvokeCommand('#media-library-add-form-wrapper .media-library-add-form-media', 'focus')); } - // Move the focus to the add form wrapper. - $response->addCommand(new InvokeCommand('#media-library-add-form-wrapper', 'focus')); return $response; } diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php index 6a02d48187..4a01ef7f62 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php @@ -827,8 +827,8 @@ public function testWidgetUpload() { $assert_session->assertWaitOnAjaxRequest(); $page->attachFileToField('Add files', $this->container->get('file_system')->realpath($png_image->uri)); $assert_session->assertWaitOnAjaxRequest(); - // Assert the focus is set on the updated media field. - $this->assertJsCondition('jQuery("#media-library-add-form-wrapper").is(":focus")'); + // Assert the focus is shifted to the added media items. + $this->assertJsCondition('jQuery("#media-library-add-form-wrapper .media-library-add-form-media").is(":focus")'); // Assert the media item fields are shown and the vertical tabs are no // longer shown. $assert_session->elementExists('css', '.media-library-add-form__fields'); @@ -840,8 +840,9 @@ public function testWidgetUpload() { // Assert the remove message is shown. $filename = $png_image->filename; $assert_session->pageTextContains("The media item $filename has been removed."); - // Assert the focus is set on the updated media field. - $this->assertJsCondition('jQuery("#media-library-add-form-wrapper").is(":focus")'); + // Assert the focus is shifted to the first tabbable element of the add + // form, which should be the source field. + $this->assertJsCondition('jQuery("#media-library-add-form-wrapper :tabbable").is(":focus")'); $assert_session->elementNotExists('css', '.media-library-add-form__fields'); $assert_session->elementExists('css', '.media-library-menu'); } @@ -953,8 +954,8 @@ public function testWidgetOEmbed() { $page->fillField('Add Type Five via URL', $video_url); $page->pressButton('Add'); $assert_session->assertWaitOnAjaxRequest(); - // Assert the focus is set on the updated media field. - $this->assertJsCondition('jQuery("#media-library-add-form-wrapper").is(":focus")'); + // Assert the focus is shifted to the added media items. + $this->assertJsCondition('jQuery("#media-library-add-form-wrapper .media-library-add-form-media").is(":focus")'); // Assert the media item fields are shown and the vertical tabs are no // longer shown. $assert_session->elementExists('css', '.media-library-add-form__fields'); @@ -965,8 +966,9 @@ public function testWidgetOEmbed() { $assert_session->assertWaitOnAjaxRequest(); // Assert the remove message is shown. $assert_session->pageTextContains("The media item $video_title has been removed."); - // Assert the focus is set on the updated media field. - $this->assertJsCondition('jQuery("#media-library-add-form-wrapper").is(":focus")'); + // Assert the focus is shifted to the first tabbable element of the add + // form, which should be the source field. + $this->assertJsCondition('jQuery("#media-library-add-form-wrapper :tabbable").is(":focus")'); $assert_session->elementNotExists('css', '.media-library-add-form__fields'); $assert_session->elementExists('css', '.media-library-menu'); }