diff --git a/modules/ui_patterns_legacy/src/ComponentConverter.php b/modules/ui_patterns_legacy/src/ComponentConverter.php
index 32e3a63151b4d044fb2f1bb43bb7d0c547ad51e4..d3de8269f43dab2849accdbe239a20f04f82ec3e 100644
--- a/modules/ui_patterns_legacy/src/ComponentConverter.php
+++ b/modules/ui_patterns_legacy/src/ComponentConverter.php
@@ -4,8 +4,8 @@ declare(strict_types = 1);
 
 namespace Drupal\ui_patterns_legacy;
 
+use Drupal\Core\Render\Component\Exception\InvalidComponentDataException;
 use Drupal\sdc\Component\ComponentValidator;
-use Drupal\sdc\Exception\InvalidComponentDataException;
 
 /**
  * Component converter.
@@ -34,6 +34,9 @@ class ComponentConverter {
     $target = $this->addProperty('description', $source, 'description', $target);
     $target = $this->addProperty('category', $source, 'group', $target);
     $target = $this->addProperty('links', $source, 'links', $target);
+    $target = $this->addProperty('use', $source, '_template', $target);
+    $target = $this->addProperty('icon_map', $source, 'icon_map', $target);
+    $target = $this->addProperty('icon_path', $source, 'icon_path', $target);
     if (\array_key_exists('variants', $source)) {
       $target['variants'] = $this->getVariants($source);
     }
diff --git a/modules/ui_patterns_legacy/src/Element/PatternPreview.php b/modules/ui_patterns_legacy/src/Element/PatternPreview.php
index b65f4e51db0574cbed26166ef7d1b05ccdf0d041..9e52d9ee72b1e76453b3ff62d3b2b122b620fbfa 100644
--- a/modules/ui_patterns_legacy/src/Element/PatternPreview.php
+++ b/modules/ui_patterns_legacy/src/Element/PatternPreview.php
@@ -53,7 +53,7 @@ class PatternPreview extends Pattern {
     $slots = $story["slots"] ?? [];
     $props = $story["props"] ?? [];
     $slots = array_merge($element["#slots"], $slots);
-    $element["#slots"] = $manager::processStoriesSlots($slots);
+    $element["#slots"] = self::processStoriesSlots($slots);
     $element["#props"] = array_merge($element["#props"], $props);
     return $element;
   }
diff --git a/modules/ui_patterns_library/src/Element/ComponentStory.php b/modules/ui_patterns_library/src/Element/ComponentStory.php
index 4e68d5006f2e9fb3e2809c49a73b98c695e7fbd1..19dba5268c161a182ae4d9b5282a02a8ddb8b28b 100644
--- a/modules/ui_patterns_library/src/Element/ComponentStory.php
+++ b/modules/ui_patterns_library/src/Element/ComponentStory.php
@@ -50,7 +50,7 @@ class ComponentStory extends ComponentElement {
     }
     $story = $component["stories"][$story_id];
     $slots = array_merge($element["#slots"] ?? [], $story["slots"] ?? []);
-    $element["#slots"] = $manager::processStoriesSlots($slots);
+    $element["#slots"] = self::processStoriesSlots($slots);
     $element["#props"] = array_merge($element["#props"] ?? [], $story["props"] ?? []);
     return $element;
   }
diff --git a/src/ComponentPluginManager.php b/src/ComponentPluginManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..737cfaa21edc1e731e4260693d857fa8b49b09f0
--- /dev/null
+++ b/src/ComponentPluginManager.php
@@ -0,0 +1,165 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\ui_patterns;
+
+use Drupal\Component\Plugin\CategorizingPluginManagerInterface;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\ThemeHandlerInterface;
+use Drupal\Core\File\FileSystemInterface;
+use Drupal\Core\Theme\ThemeManagerInterface;
+use Drupal\sdc\Component\ComponentValidator;
+use Drupal\sdc\Component\SchemaCompatibilityChecker;
+use Drupal\sdc\ComponentNegotiator;
+use Drupal\sdc\ComponentPluginManager as SdcPluginManager;
+use Drupal\ui_patterns\SchemaManager\ReferencesResolver;
+
+/**
+ * UI Patterns extension of SDC component plugin manager.
+ */
+class ComponentPluginManager extends SdcPluginManager implements CategorizingPluginManagerInterface {
+
+  /**
+   * Cache key prefix to use in the cache backend.
+   */
+  const CACHE_KEY = 'ui_patterns';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(
+    ModuleHandlerInterface $module_handler,
+    ThemeHandlerInterface $themeHandler,
+    CacheBackendInterface $cacheBackend,
+    ConfigFactoryInterface $configFactory,
+    ThemeManagerInterface $themeManager,
+    ComponentNegotiator $componentNegotiator,
+    FileSystemInterface $fileSystem,
+    SchemaCompatibilityChecker $compatibilityChecker,
+    ComponentValidator $componentValidator,
+    string $appRoot,
+    protected PropTypePluginManager $propTypePluginManager,
+    protected ReferencesResolver $referencesSolver,
+  ) {
+    parent::__construct(
+      $module_handler,
+      $themeHandler,
+      $cacheBackend,
+      $configFactory,
+      $themeManager,
+      $componentNegotiator,
+      $fileSystem,
+      $compatibilityChecker,
+      $componentValidator,
+      $appRoot
+    );
+    $this->setCacheBackend($cacheBackend, self::CACHE_KEY);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function alterDefinitions(&$definitions) {
+    parent::alterDefinitions($definitions);
+    foreach ($definitions as $component_id => $definition) {
+      $definition = $this->annotateProps($definition);
+      $definition = $this->resolveTemplatePath($definition);
+      $definitions[$component_id] = $definition;
+    }
+  }
+
+  /**
+   * Annotate each prop in a component definition.
+   *
+   * This is the main purpose of overriding SDC component plugin manager.
+   * We add a 'ui_patterns' object in each prop schema of the definition.
+   */
+  protected function annotateProps(array $definition): array {
+    if (!isset($definition['props'])) {
+      return $definition;
+    }
+    if (!isset($definition['props']['properties'])) {
+      return $definition;
+    }
+    foreach ($definition['props']['properties'] as $prop_id => $prop) {
+      $prop_type = $this->propTypePluginManager->getPropTypePlugin($prop);
+      if (isset($prop['$ref']) && str_starts_with($prop['$ref'], "ui-patterns://")) {
+        // Resolve prop schema here, because:
+        // - Drupal\sdc\Component\ComponentValidator::getClassProps() is
+        //   executed before schema references are resolved, so SDC believe
+        //   a reference is a PHP namespace.
+        // - It is not possible to propose a patch to SDC because
+        //   SchemaStorage::resolveRefSchema() is not recursively resolving
+        //   the schemas anyway.
+        $prop = $this->referencesSolver->resolve($prop);
+      }
+      $prop['ui_patterns']['type_definition'] = $prop_type;
+      $prop['ui_patterns']["summary"] = $prop_type->getSummary($prop);
+      $definition['props']['properties'][$prop_id] = $prop;
+    }
+    return $definition;
+  }
+
+  /**
+   * Resolve template path.
+   *
+   * SDC is not allowing to have a custom template property because it is always
+   * overriding its value. So we use _template instead.
+   * See: https://www.drupal.org/project/drupal/issues/3390717
+   */
+  protected function resolveTemplatePath(array $definition): array {
+    if (!isset($definition["_template"])) {
+      return $definition;
+    }
+    $definition["template"] = $definition["_template"];
+    unset($definition["_template"]);
+    if (str_starts_with($definition["template"], "@")) {
+      // @todo resolve namespace.
+    }
+    return $definition;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCategories() {
+    // Fetch all categories from definitions and remove duplicates.
+    $categories = array_unique(array_values(array_map(function ($definition) {
+      return $definition['group'];
+    }, $this->getDefinitions())));
+    natcasesort($categories);
+    return $categories;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSortedDefinitions(array $definitions = NULL) {
+    // Sort the plugins first by category, then by label.
+    $definitions = $definitions ?? $this->getDefinitions();
+    uasort($definitions, function ($a, $b) use ($label_key) {
+      if ((string) $a['group'] != (string) $b['group']) {
+        return strnatcasecmp($a['group'], $b['group']);
+      }
+      return strnatcasecmp($a[$label_key], $b[$label_key]);
+    });
+    return $definitions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getGroupedDefinitions(?array $definitions = NULL): array {
+    $definitions = $definitions ?: $this->getDefinitions();
+    $groups = [];
+    foreach ($definitions as $id => $definition) {
+      $group = $definition["group"] ?? "Other";
+      $groups[$group][$id] = $definition;
+    }
+    return $groups;
+  }
+
+}
diff --git a/src/Element/ComponentElement.php b/src/Element/ComponentElement.php
index 6d73416363f126da17400d5bda776d799084e53a..edca327e2c022076c8d4729b1225bd6e51f0f561 100644
--- a/src/Element/ComponentElement.php
+++ b/src/Element/ComponentElement.php
@@ -5,8 +5,8 @@ declare(strict_types = 1);
 namespace Drupal\ui_patterns\Element;
 
 use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\Render\Element\ComponentElement as SdcComponentElement;
 use Drupal\Core\Render\RenderableInterface;
-use Drupal\sdc\Element\ComponentElement as SdcComponentElement;
 
 /**
  * Empty for now. Act as a proxy between SDC element and our additions.
@@ -79,4 +79,38 @@ class ComponentElement extends SdcComponentElement {
     return $slot;
   }
 
+  /**
+   * Process stories slots.
+   *
+   * Stories slots have no "#" prefix in render arrays. Let's add them.
+   * A bit like UI Patterns 1.x's PatternPreview::getPreviewMarkup()
+   * This method belongs here because used by both ui_patterns_library and
+   * ui_patterns_legacy.
+   */
+  public static function processStoriesSlots(array $slots): array {
+    foreach ($slots as $slot_id => $slot) {
+      if (!is_array($slot)) {
+        continue;
+      }
+      if (array_is_list($slot)) {
+        $slots[$slot_id] = self::processStoriesSlots($slot);
+      }
+      $slot_keys = array_keys($slot);
+      $render_keys = ["theme", "type", "markup", "plain_text"];
+      if (count(array_intersect($slot_keys, $render_keys)) > 0) {
+        foreach ($slot as $key => $value) {
+          if (is_array($value)) {
+            $value = self::processStoriesSlots($value);
+          }
+          if (str_starts_with($key, "#")) {
+            continue;
+          }
+          $slots[$slot_id]["#" . $key] = $value;
+          unset($slots[$slot_id][$key]);
+        }
+      }
+    }
+    return $slots;
+  }
+
 }
diff --git a/src/Sdc/ComponentPluginManagerDecorator.php b/src/Sdc/ComponentPluginManagerDecorator.php
deleted file mode 100644
index 6cf252d68d6a6f7041b66cf215fe1266f1ef9e3a..0000000000000000000000000000000000000000
--- a/src/Sdc/ComponentPluginManagerDecorator.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?php
-
-declare(strict_types = 1);
-
-namespace Drupal\ui_patterns\Sdc;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Extension\ThemeHandlerInterface;
-use Drupal\Core\File\FileSystemInterface;
-use Drupal\Core\Theme\ThemeManagerInterface;
-use Drupal\sdc\Component\ComponentValidator;
-use Drupal\sdc\Component\SchemaCompatibilityChecker;
-use Drupal\sdc\ComponentNegotiator;
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\sdc\Plugin\Component;
-use Drupal\ui_patterns\PropTypePluginManager;
-use Drupal\ui_patterns\SourcePluginManager;
-
-/**
- * Plugin Manager for *.ui_patterns.yml configuration files.
- *
- * Plugin Manager overwrites getDiscovery() to provide a decorated
- * Discovery. Decoration of the service seems not possible for me.
- * Probably there is more gentle way.
- *
- * @see plugin_api
- *
- * @internal
- */
-abstract class ComponentPluginManagerDecorator extends ComponentPluginManager {
-
-  /**
-   *
-   */
-  public function __construct(
-    protected ComponentPluginManager $parentSdcPluginManager,
-    protected PropTypePluginManager $propTypePluginManager,
-    protected SourcePluginManager $sourcePluginManager,
-    ModuleHandlerInterface $module_handler,
-    ThemeHandlerInterface $themeHandler,
-    CacheBackendInterface $cacheBackend,
-    ConfigFactoryInterface $configFactory,
-    ThemeManagerInterface $themeManager,
-    ComponentNegotiator $componentNegotiator,
-    FileSystemInterface $fileSystem,
-    SchemaCompatibilityChecker $compatibilityChecker,
-    ComponentValidator $componentValidator,
-    string $appRoot,
-  ) {
-    parent::__construct(
-      $module_handler,
-      $themeHandler,
-      $cacheBackend,
-      $configFactory,
-      $themeManager,
-      $componentNegotiator,
-      $fileSystem,
-      $compatibilityChecker,
-      $componentValidator,
-      $appRoot
-    );
-    $this->setCacheBackend($cacheBackend, $this->getCacheKey());
-  }
-
-  /**
-   *
-   */
-  public function createInstance($plugin_id, array $configuration = []): Component {
-    if (parent::hasDefinition($plugin_id)) {
-      return parent::createInstance($plugin_id, $configuration);
-    }
-    else {
-      return $this->parentSdcPluginManager->createInstance($plugin_id, $configuration);
-    }
-  }
-
-  /**
-   * Returns the cache key for the decorated service.
-   *
-   * @return string
-   *   The cache key.
-   */
-  abstract protected function getCacheKey();
-
-  /**
-   * {@inheritdoc}
-   */
-  public function find(string $component_id): Component {
-    if (parent::hasDefinition($component_id)) {
-      return parent::find($component_id);
-    }
-    return $this->parentSdcPluginManager->find($component_id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAllComponents(): array {
-    $original_components = $this->parentSdcPluginManager->getAllComponents();
-    return array_merge($original_components, parent::getAllComponents());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefinitions() {
-    $decorated_definitions = parent::getDefinitions();
-    $original_definitions = $this->parentSdcPluginManager->getDefinitions();
-    return array_merge($original_definitions, $decorated_definitions);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
-    $original_definition = parent::getDefinition($plugin_id, FALSE);
-    return $original_definition ?? $this->parentSdcPluginManager->getDefinition($plugin_id, $exception_on_invalid);
-  }
-
-}
diff --git a/src/Sdc/UiPatternsSdcPluginManager.php b/src/Sdc/UiPatternsSdcPluginManager.php
deleted file mode 100644
index 5759a65ffdf032a189deb501495f4e17034476db..0000000000000000000000000000000000000000
--- a/src/Sdc/UiPatternsSdcPluginManager.php
+++ /dev/null
@@ -1,134 +0,0 @@
-<?php
-
-declare(strict_types = 1);
-
-namespace Drupal\ui_patterns\Sdc;
-
-/**
- * Plugin Manager for....
- *
- * @see plugin_api
- *
- * @internal
- */
-class UiPatternsSdcPluginManager extends ComponentPluginManagerDecorator {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getCacheKey() {
-    return 'ui_patterns';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterDefinitions(&$definitions) {
-    parent::alterDefinitions($definitions);
-    // @todo injection.
-    $resolver = \Drupal::service('ui_patterns.schema_reference_solver');
-    foreach ($definitions as $component_id => $definition) {
-      if (!isset($definition['props'])) {
-        continue;
-      }
-
-      if (!isset($definition['props']['properties'])) {
-        continue;
-      }
-      foreach ($definition['props']['properties'] as $prop_id => $prop) {
-        $prop = $this->replacePhpNamespace($prop);
-        $prop_type = $this->propTypePluginManager->getPropTypePlugin($prop);
-        if (isset($prop['$ref']) && str_starts_with($prop['$ref'], "ui-patterns://")) {
-          // Resolve prop schema here, because:
-          // - Drupal\sdc\Component\ComponentValidator::getClassProps() is
-          //   executed before schema references are resolved, so SDC believe
-          //   a reference is a PHP namespace.
-          // - It is not possible to propose a patch to SDC because
-          //   SchemaStorage::resolveRefSchema() is not recursively resolving
-          //   the schemas anyway.
-          $prop = $resolver->resolve($prop);
-        }
-        $prop['ui_patterns']['type_definition'] = $prop_type;
-        $prop['ui_patterns']["summary"] = $prop_type->getSummary($prop);
-        $definition['props']['properties'][$prop_id] = $prop;
-      }
-      $definitions[$component_id] = $definition;
-    }
-  }
-
-  /**
-   * Replace PHP namespace in schema's type.
-   *
-   * SDC allows namespaced PHP classes as prop types. This is not compliant with
-   * JSON schema, and props using this are ignored by SDC during JSON schema
-   * validation. So let replace them.
-   */
-  protected function replacePhpNamespace(array $schema): array {
-    if (!isset($schema['type'])) {
-      return $schema;
-    }
-    if (!is_string($schema['type'])) {
-      return $schema;
-    }
-    $mappings = [
-      'Drupal\Core\Template\Attribute' => "ui-patterns://attributes",
-      '\Drupal\Core\Template\Attribute' => "ui-patterns://attributes",
-    ];
-    foreach ($mappings as $namespace => $ref) {
-      if ($schema['type'] == $namespace) {
-        unset($schema['type']);
-        $schema['$ref'] = $ref;
-        return $schema;
-      }
-    }
-    return $schema;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getGroupedDefinitions(?array $definitions = NULL): array {
-    $definitions = $definitions ?: $this->getDefinitions();
-    $groups = [];
-    foreach ($definitions as $id => $definition) {
-      $group = $definition["group"] ?? "Other";
-      $groups[$group][$id] = $definition;
-    }
-    return $groups;
-  }
-
-  /**
-   * Process stories slots.
-   *
-   * Stories slots have no "#" prefix in render arrays. Let's add them.
-   * A bit like UI Patterns 1.x's PatternPreview::getPreviewMarkup()
-   * This method belongs here because used by both ui_patterns_library and
-   * ui_patterns_legacy.
-   */
-  public static function processStoriesSlots(array $slots): array {
-    foreach ($slots as $slot_id => $slot) {
-      if (!is_array($slot)) {
-        continue;
-      }
-      if (array_is_list($slot)) {
-        $slots[$slot_id] = self::processStoriesSlots($slot);
-      }
-      $slot_keys = array_keys($slot);
-      $render_keys = ["theme", "type", "markup", "plain_text"];
-      if (count(array_intersect($slot_keys, $render_keys)) > 0) {
-        foreach ($slot as $key => $value) {
-          if (is_array($value)) {
-            $value = self::processStoriesSlots($value);
-          }
-          if (str_starts_with($key, "#")) {
-            continue;
-          }
-          $slots[$slot_id]["#" . $key] = $value;
-          unset($slots[$slot_id][$key]);
-        }
-      }
-    }
-    return $slots;
-  }
-
-}
diff --git a/tests/modules/ui_patterns_test/components/button/button.component.yml b/tests/modules/ui_patterns_test/components/button/button.component.yml
index 9bc44c329bcef8af80c99ed1d57dd939f195b462..b2b75579c92bcf6735b584b7ce1f5da64e94f078 100644
--- a/tests/modules/ui_patterns_test/components/button/button.component.yml
+++ b/tests/modules/ui_patterns_test/components/button/button.component.yml
@@ -4,7 +4,7 @@ description: "For actions in forms, dialogs, and more with support for multiple
 links:
   - "https://getbootstrap.com/docs/5.3/components/buttons/"
 group: "Button"
-template: pattern-button.html.twig
+_template: ../../components/button/pattern-button.html.twig
 variants:
   default:
     title: "Default"
diff --git a/tests/modules/ui_patterns_test/components/button/button.twig b/tests/modules/ui_patterns_test/components/button/button.twig
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tests/modules/ui_patterns_test/components/progress/progress.component.yml b/tests/modules/ui_patterns_test/components/progress/progress.component.yml
index bab53b35dece2c5380468b5a882b41cce89f14f4..06e31808140e540f6e23d31452e4088b18118a39 100644
--- a/tests/modules/ui_patterns_test/components/progress/progress.component.yml
+++ b/tests/modules/ui_patterns_test/components/progress/progress.component.yml
@@ -3,7 +3,7 @@ name: "Progress"
 description: "The progress element displays an indicator showing the completion progress of a task, typically in the form of a bar. Progress components are built with two HTML elements, some CSS to set the width, and a few attributes. Bootstrap does not use the HTML5 <progress> element, ensuring you can stack progress bars, animate them, and place text labels over them."
 links:
   - "https://getbootstrap.com/docs/5.3/components/progress/"
-template: path/to/template/progress.twig
+_template: path/to/template/progress.twig
 variants:
   default:
     title: "Default"
diff --git a/tests/modules/ui_patterns_test/components/progress/progress.twig b/tests/modules/ui_patterns_test/components/progress/progress.twig
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/ui_patterns.services.yml b/ui_patterns.services.yml
index cd39e79bedebc51407e482151084773419c96ea2..0a1de5144aed5780300bed9db546c90385d435dd 100644
--- a/ui_patterns.services.yml
+++ b/ui_patterns.services.yml
@@ -1,26 +1,8 @@
 services:
   # Plugins managers.
-  plugin.manager.ui_patterns_prop_type:
-    class: Drupal\ui_patterns\PropTypePluginManager
-    arguments:
-      - "@container.namespaces"
-      - "@cache.discovery"
-      - "@module_handler"
-      - '@Drupal\sdc\Component\SchemaCompatibilityChecker'
-  plugin.manager.ui_patterns_source:
-    class: Drupal\ui_patterns\SourcePluginManager
-    parent: default_plugin_manager
-
-  # SDC extension.
-  ui_patterns.plugin.manager.sdc:
-    class: Drupal\ui_patterns\Sdc\UiPatternsSdcPluginManager
-    decorates: plugin.manager.sdc
-    decoration_priority: 9
-    public: false
+  plugin.manager.sdc:
+    class: Drupal\ui_patterns\ComponentPluginManager
     arguments:
-      - "@ui_patterns.plugin.manager.sdc.inner"
-      - "@plugin.manager.ui_patterns_prop_type"
-      - "@plugin.manager.ui_patterns_source"
       - "@module_handler"
       - "@theme_handler"
       - "@cache.discovery"
@@ -31,6 +13,18 @@ services:
       - '@Drupal\sdc\Component\SchemaCompatibilityChecker'
       - '@Drupal\sdc\Component\ComponentValidator'
       - "%app.root%"
+      - "@plugin.manager.ui_patterns_prop_type"
+      - "@ui_patterns.schema_reference_solver"
+  plugin.manager.ui_patterns_prop_type:
+    class: Drupal\ui_patterns\PropTypePluginManager
+    arguments:
+      - "@container.namespaces"
+      - "@cache.discovery"
+      - "@module_handler"
+      - '@Drupal\sdc\Component\SchemaCompatibilityChecker'
+  plugin.manager.ui_patterns_source:
+    class: Drupal\ui_patterns\SourcePluginManager
+    parent: default_plugin_manager
 
   # Builders
   ui_patterns.component_element_builder: