diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php
index 497d83346bb53d704c0cb0ffb5b51ef3c20885be..4b87718853bddc34639d0b8c431030fd42dd830b 100644
--- a/core/modules/media_library/src/Form/AddFormBase.php
+++ b/core/modules/media_library/src/Form/AddFormBase.php
@@ -328,11 +328,8 @@ protected function buildEntityFormElement(MediaInterface $media, array $form, Fo
     }
     $form_display->buildForm($media, $element['fields'], $form_state);
 
-    // We hide the preview of the uploaded file in the image widget with CSS, so
-    // set a property so themes and form_alter hooks can easily identify the
-    // source field.
-    // @todo Improve hiding file widget elements in
-    //   https://www.drupal.org/project/drupal/issues/2987921
+    // Add source field name so that it can be identified in form alter and
+    // widget alter hooks.
     $element['fields']['#source_field_name'] = $this->getSourceFieldName($media->bundle->entity);
 
     // The revision log field is currently not configurable from the form
diff --git a/core/modules/media_library/src/Form/FileUploadForm.php b/core/modules/media_library/src/Form/FileUploadForm.php
index d9b377d4a1b8fd8b2eb9f5d6fa807f9a39d4e07b..3299b84e152e36a0babb1af6d62864c8d9fea6eb 100644
--- a/core/modules/media_library/src/Form/FileUploadForm.php
+++ b/core/modules/media_library/src/Form/FileUploadForm.php
@@ -244,6 +244,52 @@ public function processUploadElement(array $element, FormStateInterface $form_st
     return $element;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function buildEntityFormElement(MediaInterface $media, array $form, FormStateInterface $form_state, $delta) {
+    $element = parent::buildEntityFormElement($media, $form, $form_state, $delta);
+    $source_field = $this->getSourceFieldName($media->bundle->entity);
+    if (isset($element['fields'][$source_field])) {
+      $element['fields'][$source_field]['widget'][0]['#process'][] = [static::class, 'hideExtraSourceFieldComponents'];
+    }
+    return $element;
+  }
+
+  /**
+   * Processes an image or file source field element.
+   *
+   * @param array $element
+   *   The entity form source field element.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current form state.
+   * @param $form
+   *   The complete form.
+   *
+   * @return array
+   *   The processed form element.
+   */
+  public static function hideExtraSourceFieldComponents($element, FormStateInterface $form_state, $form) {
+    // Remove original button added by ManagedFile::processManagedFile().
+    if (!empty($element['remove_button'])) {
+      $element['remove_button']['#access'] = FALSE;
+    }
+    // Remove preview added by ImageWidget::process().
+    if (!empty($element['preview'])) {
+      $element['preview']['#access'] = FALSE;
+    }
+
+    $element['#title_display'] = 'none';
+    $element['#description_display'] = 'none';
+
+    // Remove the filename display.
+    foreach ($element['#files'] as $file) {
+      $element['file_' . $file->id()]['filename']['#access'] = FALSE;
+    }
+
+    return $element;
+  }
+
   /**
    * Submit handler for the upload button, inside the managed_file element.
    *
diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php
index c5f436e5d4a6e4a4c7d0c85f32909de10b59f195..649b16f52527cc5a50a8b6c75215d462ac25e5cc 100644
--- a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php
+++ b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php
@@ -2294,8 +2294,15 @@ protected function assertMediaAdded($index = 0) {
     $assert_session->pageTextMatches('/The media items? ha(s|ve) been created but ha(s|ve) not yet been saved. Fill in any required fields and save to add (it|them) to the media library./');
     $assert_session->elementAttributeContains('css', $selector, 'aria-label', 'Added media items');
 
-    $this->assertElementExistsAfterWait('css', '[data-drupal-selector="edit-media-' . $index . '-fields"]');
+    $fields = $this->assertElementExistsAfterWait('css', '[data-drupal-selector="edit-media-' . $index . '-fields"]');
     $assert_session->elementNotExists('css', '.js-media-library-menu');
+
+    // Assert extraneous components were removed in
+    // FileUploadForm::hideExtraSourceFieldComponents().
+    $assert_session->elementNotExists('css', '[data-drupal-selector$="preview"]', $fields);
+    $assert_session->buttonNotExists('Remove', $fields);
+    $assert_session->elementNotExists('css', '[data-drupal-selector$="filename"]', $fields);
+    $assert_session->elementNotExists('css', '.file-size', $fields);
   }
 
   /**
diff --git a/core/themes/classy/classy.theme b/core/themes/classy/classy.theme
index 4407c9a528249b2c27c54868f21c4c1b806b7c89..c9611e44a3f890e300eeb2679f54f477640eae83 100644
--- a/core/themes/classy/classy.theme
+++ b/core/themes/classy/classy.theme
@@ -32,3 +32,13 @@ function classy_form_alter(array &$form, FormStateInterface $form_state, $form_i
     $form['#attributes']['class'][] = 'media-library-views-form';
   }
 }
+
+/**
+ * Implements hook_preprocess_image_widget().
+ */
+function classy_preprocess_image_widget(array &$variables) {
+  $data = &$variables['data'];
+  if (isset($data['preview']['#access']) && $data['preview']['#access'] === FALSE) {
+    unset($data['preview']);
+  }
+}
diff --git a/core/themes/seven/css/theme/media-library.css b/core/themes/seven/css/theme/media-library.css
index 8c75fda49ff730ae49019e294779b114b1ace396..80217a64bcf29a221a494c8aa87c14a7415e00e5 100644
--- a/core/themes/seven/css/theme/media-library.css
+++ b/core/themes/seven/css/theme/media-library.css
@@ -658,15 +658,6 @@
   border-bottom: 0;
 }
 
-/* @todo Remove in https://www.drupal.org/project/drupal/issues/2987921 */
-.media-library-add-form__source-field .file,
-.media-library-add-form__source-field .button,
-.media-library-add-form__source-field .image-preview,
-.media-library-add-form__source-field .form-type-managed-file > label,
-.media-library-add-form__source-field .file-size {
-  display: none;
-}
-
 .media-library-add-form__preview {
   display: flex;
   align-items: center;