diff --git a/modules/features_ui/css/features_ui.admin.css b/modules/features_ui/css/features_ui.admin.css
index bde7b01eb28598420764c4f306ef88237fae59b1..e2dd23d016a9b2f9ec2e28ffc6d54c735802a2c5 100644
--- a/modules/features_ui/css/features_ui.admin.css
+++ b/modules/features_ui/css/features_ui.admin.css
@@ -218,6 +218,15 @@ span.features-component-list .features-dependency {
   font-weight: bold !important;
 }
 
+.features-diff-header-action {
+  font-size: small;
+}
+
+.js-features-filter-hidden,
+.js-features-diff-hidden {
+  display: none !important;
+}
+
 .features-filter .form-text {
   width: 200px;
 }
diff --git a/modules/features_ui/features_ui.libraries.yml b/modules/features_ui/features_ui.libraries.yml
index 07a4d490aa54707a03833bf5ca336a35ce0816ac..da7ab9a5668fdfb53647a5e73e96115606f6f97b 100644
--- a/modules/features_ui/features_ui.libraries.yml
+++ b/modules/features_ui/features_ui.libraries.yml
@@ -1,5 +1,4 @@
 drupal.features_ui.admin:
-  version: VERSION
   css:
     theme:
       css/features_ui.admin.css: {}
diff --git a/modules/features_ui/js/features_ui.admin.js b/modules/features_ui/js/features_ui.admin.js
index e5906560ce3a4de2083101857239b353a7e9f748..ca6490eaa93ce49068455d4a120e3aac233f09d4 100644
--- a/modules/features_ui/js/features_ui.admin.js
+++ b/modules/features_ui/js/features_ui.admin.js
@@ -69,7 +69,7 @@ jQuery.fn.sortElements = (function () {
 
 })();
 
-(function ($) {
+(function ($, Drupal) {
 
   "use strict";
 
@@ -81,7 +81,7 @@ jQuery.fn.sortElements = (function () {
       // For (var configType in drupalSettings.features.conflicts) {.
           if (drupalSettings.features.conflicts) {
             var configConflicts = drupalSettings.features.conflicts;
-            $('.js-features-export-wrapper input[type=checkbox]:not(.js-features-checkall)', context).each(function () {
+            $('.js-features-export-wrapper .features-export-parent input[type=checkbox]:not(.js-features-filter)', context).each(function () {
               var key = $(this).attr('name');
               var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
               var component = matches[1];
@@ -159,10 +159,13 @@ jQuery.fn.sortElements = (function () {
         else {
           $(item).removeAttr('checked');
         }
-        $(newParent).parents('.js-features-export-list').removeClass('features-export-empty');
+        var $newParents = $(newParent);
+        $newParents.parents('.js-features-export-list').removeClass('features-export-empty');
+        // Unhide the config type group.
+        $newParents.parents('.features-export-parent').removeClass('features-filter-hidden');
 
         // re-sort new list of checkboxes based on labels.
-        $(newParent).find('label').sortElements(
+        $newParents.find('label').sortElements(
           function (a, b) {
             return $(a).text() > $(b).text() ? 1 : -1;
           },
@@ -199,7 +202,7 @@ jQuery.fn.sortElements = (function () {
         // the auto-detected items.
         var items = [];  // Will contain a list of selected items exported to feature.
         var components = {};  // Contains object of component names that have checked items.
-        $('.js-features-export-wrapper input[type=checkbox]:not(.js-features-checkall):checked', context).each(function () {
+        $('.js-features-export-wrapper .features-export-parent input[type=checkbox]:not(.js-features-filter):checked', context).each(function () {
           var key = $(this).attr('name');
           var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
           components[matches[1]] = matches[1];
@@ -257,7 +260,7 @@ inTimeout--; }
       }
 
       // Handle component selection UI.
-      $('.js-features-export-wrapper input[type=checkbox]', context).click(function () {
+      $('.js-features-export-wrapper .features-export-parent input[type=checkbox]', context).click(function () {
         _resetTimeout();
         if ($(this).hasClass('component-select')) {
           moveCheckbox(this, 'added', true);
@@ -277,17 +280,56 @@ inTimeout--; }
 
       // Handle select/unselect all.
       $('.js-features-checkall', context).click(function () {
+        let $text = $(this).next();
         if ($(this).prop('checked')) {
           _checkAll(true);
-          $(this).next().html(Drupal.t('Deselect all'));
+          $text.text(Drupal.t('Deselect all'))
+            .attr('title', Drupal.t('Deselect all currently expanded configurations'));
         }
         else {
           _checkAll(false);
-          $(this).next().html(Drupal.t('Select all'));
+          $text.text(Drupal.t('Select all'))
+            .attr('title', Drupal.t('Select all currently expanded configurations'));
         }
         _resetTimeout();
       });
 
+      // Handle hide/show components.
+      $('.js-features-filter .features-hide-component.form-select', context).change(function () {
+        var $exportWrapper = $('.js-features-export-wrapper', context);
+        var componentType = $(this).val();
+        $exportWrapper
+            .find('.js-features-filter-hidden')
+            .removeClass('js-features-filter-hidden');
+        if (componentType) {
+          if (componentType === 'included+groups') {
+            componentType = 'included';
+            // Hide empty config components.
+            $exportWrapper.find('.js-component-count').filter(function() {
+              return $(this).text() === '0';
+            }).parents('.features-export-parent').addClass('js-features-filter-hidden');
+          }
+          $exportWrapper.find('.js-features-export-parent .js-components-' + componentType).addClass('js-features-filter-hidden');
+        }
+      });
+
+      // Collapse/Expand components.
+      $('.js-features-filter .features-toggle-components', context).click(function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+        var expandAll = Drupal.t('Expand all');
+        var collapseAll = Drupal.t('Collapse all');
+        var $this = $(this);
+        var $components = $('.features-export-component', context);
+        if (expandAll == $this.text()) {
+          $components.attr('open', true);
+          $this.text(collapseAll);
+        } else {
+          $components.attr('open', false);
+          $this.text(expandAll);
+        }
+      });
+
       // Handle filtering.
       // Provide timer for auto-refresh trigger.
       var filterTimeoutID = 0;
@@ -394,6 +436,25 @@ inTimeout--; }
           $(this).parents('tr').removeClass('selected');
         }
       });
+      // Show/Hide components.
+      $('.features-diff-header-action-link', context).click(function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+        var showAll = Drupal.t('Show all');
+        var hideAll = Drupal.t('Hide all');
+        var $this = $(this);
+        var $checkbox = $this.closest('tr').find('td:nth-child(1) input:checkbox');
+        var $elements = $this.closest('table').find('tr.diff-' + $checkbox.prop('value'));
+        if (hideAll == $this.text()) {
+          $this.text(showAll);
+          $elements.addClass('js-features-diff-hidden');
+        }
+        else {
+          $this.text(hideAll);
+          $elements.removeClass('js-features-diff-hidden');
+        }
+      });
+
       $('.features-diff-listing thead th:nth-child(2)', context).click(function () {
         var checkbox = $(this).parent().find('th input:checkbox');
         checkbox.click();
@@ -401,4 +462,4 @@ inTimeout--; }
     }
   };
 
-})(jQuery);
+})(jQuery, Drupal);
diff --git a/modules/features_ui/src/Form/FeaturesDiffForm.php b/modules/features_ui/src/Form/FeaturesDiffForm.php
index ad4094c7c406eb9cbebab4abdd84a0a0a54cd70b..f9d592e445491d4f32fa8bf403249d7bb91a54c6 100644
--- a/modules/features_ui/src/Form/FeaturesDiffForm.php
+++ b/modules/features_ui/src/Form/FeaturesDiffForm.php
@@ -134,13 +134,20 @@ class FeaturesDiffForm extends FormBase {
         $missing = $this->featuresManager->reorderMissing($this->featuresManager->detectMissing($package));
         $overrides = $this->featuresManager->detectOverrides($package, TRUE);
         if (!empty($overrides) || !empty($missing)) {
+          $header_title = $this->t(
+            '@package_name <small class="features-diff-header-action">(<a class="features-diff-header-action-link" href="#">@action</a>)</small>',
+            [
+              '@package_name' => Html::escape($package->getName()),
+              '@action' => $this->t('Hide all'),
+            ]
+          );
           $options += [
             $package->getMachineName() => [
               'row' => [
                 'data' => [
                   '#type' => 'html_tag',
                   '#tag' => 'h2',
-                  '#value' => Html::escape($package->getName()),
+                  '#value' => $header_title,
                 ],
               ],
               '#attributes' => [
diff --git a/modules/features_ui/src/Form/FeaturesEditForm.php b/modules/features_ui/src/Form/FeaturesEditForm.php
index 69acfc4080612e9b700e27c4d4c90c522e1c2721..75cb3103c932c4c60fb4e084485bf96d45bf08f3 100644
--- a/modules/features_ui/src/Form/FeaturesEditForm.php
+++ b/modules/features_ui/src/Form/FeaturesEditForm.php
@@ -278,7 +278,7 @@ class FeaturesEditForm extends FormBase {
       '#size' => 30,
     ];
 
-    list($full_name, $path) = $this->featuresManager->getExportInfo($this->package, $bundle);
+    [$full_name, $path] = $this->featuresManager->getExportInfo($this->package, $bundle);
     $form['info']['directory'] = [
       '#title' => $this->t('Path'),
       '#description' => $this->t('Path to export package using Write action, relative to root directory.'),
@@ -462,9 +462,67 @@ class FeaturesEditForm extends FormBase {
       '#hidden' => TRUE,
       '#title' => $this->t('Select all'),
       '#attributes' => [
-        'class' => ['features-checkall', 'js-features-checkall'],
+        'class' => [
+          'features-checkall',
+          'js-features-checkall',
+          'features-filter',
+          'js-features-filter',
+        ],
+      ],
+      '#label_attributes' => [
+        'title' => $this->t('Select all currently expanded configurations'),
+      ],
+    ];
+    $element['features_filter_wrapper']['toggle-components'] = [
+      '#type' => 'html_tag',
+      '#tag' => 'a',
+      '#value' => $this->t('Expand all'),
+      '#attributes' => [
+        'href' => '#',
+        'title' => $this->t('Expand/collapse components in order to "Select all".'),
+        'class' => [
+          'features-toggle-components',
+          'features-filter',
+          'js-features-filter',
+        ],
+      ],
+    ];
+    $element['features_filter_wrapper']['hide-components'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Hide'),
+      '#options' => [
+        'included' => $this->t('Normal'),
+        'included+groups' => $this->t('Normal (and empty groups)'),
+        'added' => $this->t('Added'),
+        'detected' => $this->t('Auto detected'),
+        'conflict' => $this->t('Conflict'),
+      ],
+      '#empty_option' => $this->t('- None -'),
+      '#default_value' => '',
+      '#attributes' => [
+        'class' => [
+          'features-hide-component',
+          'features-filter',
+          'js-features-filter',
+        ],
+        'title' => $this->t('Hide specific Features components'),
       ],
     ];
+    $element['features_filter_wrapper']['features_legend'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Legend'),
+      '#tree' => FALSE,
+      '#prefix' => '<div id="features-legend">',
+      '#suffix' => '</div>',
+    ];
+    $element['features_filter_wrapper']['features_legend']['legend'] = [
+      '#markup' => implode('', [
+        "<span class='features-legend-component features-legend-component--included'>" . $this->t('Normal') . '</span> ',
+        "<span class='features-legend-component features-legend-component--added'>" . $this->t('Added') . '</span> ',
+        "<span class='features-legend-component features-legend-component--detected'>" . $this->t('Auto detected') . '</span> ',
+        "<span class='features-legend-component features-legend-component--conflict'>" . $this->t('Conflict') . '</span> ',
+      ]),
+    ];
 
     $sections = ['included', 'detected', 'added'];
     $config_types = $this->featuresManager->listConfigTypes();
@@ -544,24 +602,15 @@ class FeaturesEditForm extends FormBase {
 
     $element['features_missing'] = [
       '#theme' => 'item_list',
+      '#wrapper_attributes' => [
+        'class' => [
+          'features-missing-items',
+        ],
+      ],
       '#items' => $export['missing'],
       '#title' => $this->t('Configuration missing from active site:'),
       '#suffix' => '<div class="description">' . $this->t('Import the feature to create the missing config listed above.') . '</div>',
-    ];
-
-    $element['features_legend'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Legend'),
-      '#tree' => FALSE,
-      '#prefix' => '<div id="features-legend">',
-      '#suffix' => '</div>',
-    ];
-    $element['features_legend']['legend'] = [
-      '#markup' =>
-        "<span class='features-legend-component features-legend-component--included'>" . $this->t('Normal') . "</span> " .
-        "<span class='features-legend-component features-legend-component--added'>" . $this->t('Added') . "</span> " .
-        "<span class='features-legend-component features-legend-component--detected'>" . $this->t('Auto detected') . "</span> " .
-        "<span class='features-legend-component features-legend-component--conflict'>" . $this->t('Conflict') . "</span> ",
+      '#access' => !empty($export['missing']),
     ];
 
     return $element;
