diff --git a/claro.theme b/claro.theme
index ec563a2..0143de7 100644
--- a/claro.theme
+++ b/claro.theme
@@ -259,6 +259,67 @@ function claro_element_info_alter(&$type) {
   if (isset($type['dropbutton'])) {
     $type['dropbutton']['#pre_render'][] = '_claro_dropbutton_prerender';
   }
+
+  if (isset($type['managed_file'])) {
+    $type['managed_file']['#pre_render'][] = '_claro_managed_file_prerender';
+  }
+}
+
+/**
+ * Prerender callback for Managed File element.
+ */
+function _claro_managed_file_prerender($element) {
+  if (!$element['#multiple'] && $element['#cardinality'] === 1 && empty($element['#fake_multiple'])) {
+    $element['#fake_multiple'] = TRUE;
+    $element['#theme_wrappers']['details'] = [
+      '#summary_attributes' => [],
+      '#attributes' => [
+        'open' => TRUE,
+      ],
+      '#accordion' => TRUE,
+      '#value' => NULL,
+      '#required' => $element['#required'],
+    ];
+
+    if (!empty($element['#description']) && !empty($element['#upload_validators'])) {
+      $upload_help_description = [
+        '#theme' => 'file_upload_help',
+        '#description' => '',
+        '#upload_validators' => $element['#upload_validators'],
+        '#cardinality' => $element['#cardinality'],
+      ];
+
+      $plain_description = (string) $element['#description'];
+      $validator_description = trim(preg_replace('/<!--(.|\s)*?-->/', '', \Drupal::service('renderer')->renderPlain($upload_help_description)));
+      $whole_description = trim(preg_replace('/<!--(.|\s)*?-->/', '', $plain_description));
+
+      if (($start = strpos($whole_description, $validator_description)) !== FALSE) {
+        $element['#description'] = $validator_description;
+        $element['#theme_wrappers']['details']['#description'] = [
+          '#markup' => substr($whole_description, 0, $start),
+        ];
+      }
+    }
+
+    // This is something that the file widget does for multiple file fields,
+    // but the following code breaks AJAX.
+    // @code
+    // $element['#type'] = 'details';
+    // $element['#open'] = TRUE;
+    // $element['#summary_attributes'] = new Attribute();
+    // $element['#theme'] = 'file_widget_multiple';
+    // $element['#theme_wrappers'] = ['details' => [
+    //   '#summary_attributes' => [],
+    //   '#attributes' => [
+    //     'open' => TRUE,
+    //   ],
+    //   '#accordion' => TRUE,
+    //   '#value' => NULL,
+    // ]];
+    // $element['#file_upload_title'] = $element['#title'];
+    // @endcode
+  }
+  return $element;
 }
 
 /**
diff --git a/css/src/components/details.css b/css/src/components/details.css
index 66bdfa8..6ba18c3 100644
--- a/css/src/components/details.css
+++ b/css/src/components/details.css
@@ -490,3 +490,16 @@
     border: 2px dotted;
   }
 }
+
+.required-mark::after {
+  content: "";
+  vertical-align: super;
+  display: inline-block;
+  background-image: url(../../../images/core/ee0000/required.svg);
+  background-repeat: no-repeat;
+  background-size: 0.4375rem 0.4375rem;
+  width: 0.4375rem;
+  height: 0.4375rem;
+  margin-right: 0.3em;
+  margin-left: 0.3em;
+}
diff --git a/templates/details.html.twig b/templates/details.html.twig
index 2bfcd1c..c88026c 100644
--- a/templates/details.html.twig
+++ b/templates/details.html.twig
@@ -58,6 +58,9 @@
     %}
     <summary{{ summary_attributes.addClass(summary_classes) }}>
       {{- title -}}
+      {%- if required %}
+        <span class="required-mark"></span>
+      {% endif -%}
     </summary>
   {%- endif -%}
   <div{{ content_attributes.addClass(content_wrapper_classes) }}>
