diff --git a/modules/ui_patterns_field_group/tests/src/Unit/EntityFinderTest.php b/modules/ui_patterns_field_group/tests/src/Unit/EntityFinderTest.php
index 75a60c93b12e10c9e5312817147004c03c90468d..8db3a6b0a5d49e5bae3686131da5d97ee44ba446 100644
--- a/modules/ui_patterns_field_group/tests/src/Unit/EntityFinderTest.php
+++ b/modules/ui_patterns_field_group/tests/src/Unit/EntityFinderTest.php
@@ -9,7 +9,7 @@ use Drupal\ui_patterns_field_group\Utility\EntityFinder;
 /**
  * Test entity finder utility.
  *
- * @group ui_patterns
+ * @group ui_patterns_field_group
  */
 class EntityFinderTest extends UnitTestCase {
 
diff --git a/modules/ui_patterns_views/src/Plugin/UiPatterns/Source/ViewStyleSource.php b/modules/ui_patterns_views/src/Plugin/UiPatterns/Source/ViewStyleSource.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dcb39e7e84a035de6dde9b8068c16df1aefd1c4
--- /dev/null
+++ b/modules/ui_patterns_views/src/Plugin/UiPatterns/Source/ViewStyleSource.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\ui_patterns_views\Plugin\UiPatterns\Source;
+
+use Drupal\ui_patterns\Plugin\PatternSourceBase;
+
+/**
+ * Defines view style source plugin.
+ *
+ * @UiPatternsSource(
+ *     id = "view_style",
+ *     label = @Translation("View style"),
+ *     tags = {
+ *         "view_style"
+ *     }
+ * )
+ */
+class ViewStyleSource extends PatternSourceBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSourceFields() {
+    $sources = [];
+    // The title of this group of rows. May be empty.
+    $sources[] = $this->getSourceField('title', 'title');
+    $sources[] = $this->getSourceField('rows', 'rows');
+    return $sources;
+  }
+
+}
diff --git a/modules/ui_patterns_views/src/Plugin/views/row/Pattern.php b/modules/ui_patterns_views/src/Plugin/views/row/Pattern.php
index 2a1a29934b8b47517b2564eac82982acbee78bd0..ed6d69b2ba3fd6e3c9d2f0a925ac9dafcaa2c8f6 100644
--- a/modules/ui_patterns_views/src/Plugin/views/row/Pattern.php
+++ b/modules/ui_patterns_views/src/Plugin/views/row/Pattern.php
@@ -5,8 +5,8 @@ namespace Drupal\ui_patterns_views\Plugin\views\row;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\ui_patterns\Form\PatternDisplayFormTrait;
-use Drupal\ui_patterns\UiPatternsSourceManager;
 use Drupal\ui_patterns\UiPatternsManager;
+use Drupal\ui_patterns\UiPatternsSourceManager;
 use Drupal\views\Plugin\views\field\FieldPluginBase;
 use Drupal\views\Plugin\views\row\Fields;
 use Symfony\Component\DependencyInjection\ContainerInterface;
diff --git a/modules/ui_patterns_views/src/Plugin/views/style/Pattern.php b/modules/ui_patterns_views/src/Plugin/views/style/Pattern.php
new file mode 100755
index 0000000000000000000000000000000000000000..317404be674df0a0dfb2f3712c17195360504ed1
--- /dev/null
+++ b/modules/ui_patterns_views/src/Plugin/views/style/Pattern.php
@@ -0,0 +1,179 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\ui_patterns_views\Plugin\views\style;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\ui_patterns\Element\PatternContext;
+use Drupal\ui_patterns\Form\PatternDisplayFormTrait;
+use Drupal\ui_patterns\UiPatternsManager;
+use Drupal\ui_patterns\UiPatternsSourceManager;
+use Drupal\ui_patterns_settings\UiPatternsSettings;
+use Drupal\views\Plugin\views\style\StylePluginBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Style plugin to render items in a pattern field.
+ *
+ * @ingroup views_style_plugins
+ *
+ * @ViewsStyle(
+ *     id = "pattern",
+ *     title = @Translation("Pattern"),
+ *     help = @Translation("Displays content with a pattern."),
+ *     theme = "view--pattern",
+ *     display_types = {"normal"}
+ * )
+ */
+class Pattern extends StylePluginBase {
+  use PatternDisplayFormTrait;
+
+  /**
+   * UI Patterns manager.
+   *
+   * @var \Drupal\ui_patterns\UiPatternsManager
+   */
+  protected $patternsManager;
+
+  /**
+   * UI Patterns source manager.
+   *
+   * @var \Drupal\ui_patterns\UiPatternsSourceManager
+   */
+  protected $sourceManager;
+
+  /**
+   * A module manager object.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $usesRowPlugin = TRUE;
+
+  /**
+   * Constructs a Drupal\Component\Plugin\PluginBase object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\ui_patterns\UiPatternsManager $patterns_manager
+   *   UI Patterns manager.
+   * @param \Drupal\ui_patterns\UiPatternsSourceManager $source_manager
+   *   UI Patterns source manager.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   A module manager object.
+   */
+  final public function __construct(array $configuration, $plugin_id, $plugin_definition, UiPatternsManager $patterns_manager, UiPatternsSourceManager $source_manager, ModuleHandlerInterface $module_handler) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->patternsManager = $patterns_manager;
+    $this->sourceManager = $source_manager;
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('plugin.manager.ui_patterns'),
+      $container->get('plugin.manager.ui_patterns_source'),
+      $container->get('module_handler')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['pattern'] = ['default' => ''];
+    $options['pattern_variant'] = ['default' => ''];
+    $options['pattern_mapping'] = ['default' => []];
+    $options['pattern_settings'] = ['default' => []];
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @phpstan-ignore-next-line
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state): array {
+    parent::buildOptionsForm($form, $form_state);
+
+    $context = [];
+    $this->buildPatternDisplayForm($form, 'view_style', $context, $this->options);
+    $form['#element_validate'] = [[static::class, 'cleanSettings']];
+    return $form;
+  }
+
+  /**
+   * Clean up pattern settings.
+   *
+   * @param array $element
+   *   The pattern settings element.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   * @param array $form
+   *   The form definition.
+   */
+  public static function cleanSettings(array &$element, FormStateInterface $form_state, array $form): void {
+    $element_value = $form_state->getValue($element['#parents']);
+    static::processFormStateValues($element_value);
+    $form_state->setValue($element['#parents'], $element_value);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(): array {
+    $build = parent::render();
+    $pattern = $this->options['pattern'];
+
+    // We are using groups ($usesRowPlugin)
+    foreach ($build as $delta => $group) {
+      $build[$delta]['#options']['pattern'] = $pattern;
+      $build[$delta]['#options']['variant'] = $this->options['pattern_variant'];
+      $build[$delta]['#options']['context'] = new PatternContext('views_style', [
+        'view_name' => $this->view->id(),
+        'display' => $this->view->current_display,
+        'view' => $this->view->storage,
+      ]);
+
+      // Set pattern fields.
+      $fields = [];
+      $mapping = $this->options['pattern_mapping'];
+      foreach ($mapping as $source => $field) {
+        if ($field['destination'] === '_hidden') {
+          continue;
+        }
+        // Get rid of the source tag.
+        $source = \explode(':', $source)[1];
+        if ($source === 'title') {
+          $fields[$field['destination']] = $group['#title'];
+        }
+        if ($source === 'rows') {
+          $fields[$field['destination']] = $group['#rows'];
+        }
+      }
+      $build[$delta]['#options']['fields'] = $fields;
+      if (isset($this->options['pattern_settings'][$pattern]) && $this->moduleHandler->moduleExists('ui_patterns_settings')) {
+        $build[$delta]['#options']['settings'] = UiPatternsSettings::preprocess($pattern, $this->options['pattern_settings'][$pattern], $build[$delta]['#options']['variant'], FALSE);
+      }
+    }
+    return $build;
+  }
+
+}
diff --git a/modules/ui_patterns_views/templates/view--pattern.html.twig b/modules/ui_patterns_views/templates/view--pattern.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..c8397931efe0c9d8781d176e471f1caae334a054
--- /dev/null
+++ b/modules/ui_patterns_views/templates/view--pattern.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * To display a view group inside a pattern.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the wrapping element.
+ * - title: The title of this group of rows. May be empty.
+ * - options: The view plugin style options.
+ * - rows: A list of the view's row items.
+ *   - attributes: The row's HTML attributes.
+ *   - content: The row's content.
+ * - view: The view object.
+ */
+#}
+
+{% set pattern_settings = options.fields %}
+{% set pattern_settings = options.variant ? pattern_settings | merge({ 'variant': options.variant }) : pattern_settings  %}
+{% set pattern_settings = options.context ? pattern_settings | merge({ 'context': options.context }) : pattern_settings  %}
+{% set pattern_settings = attributes ? pattern_settings | merge({ 'attributes': attributes }) : pattern_settings  %}
+{% set pattern_settings = options.settings ? pattern_settings | merge(options.settings) : pattern_settings  %}
+
+{{ pattern(options.pattern, pattern_settings) }}
diff --git a/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/config/install/views.view.articles.yml b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/config/install/views.view.articles.yml
index f31f1228d56f3b0508508ad1d438246515012d11..07e8210c237fcba04014a43dc1aaa808586d373d 100644
--- a/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/config/install/views.view.articles.yml
+++ b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/config/install/views.view.articles.yml
@@ -16,85 +16,34 @@ base_table: node_field_data
 base_field: nid
 display:
   default:
-    display_plugin: default
     id: default
     display_title: Master
+    display_plugin: default
     position: 0
     display_options:
-      access:
-        type: perm
-        options:
-          perm: 'access content'
-      cache:
-        type: tag
-        options: {  }
-      query:
-        type: views_query
-        options:
-          disable_sql_rewrite: false
-          distinct: false
-          replica: false
-          query_comment: ''
-          query_tags: {  }
-      exposed_form:
-        type: basic
-        options:
-          submit_button: Apply
-          reset_button: false
-          reset_button_label: Reset
-          exposed_sorts_label: 'Sort by'
-          expose_sort_order: true
-          sort_asc_label: Asc
-          sort_desc_label: Desc
-      pager:
-        type: some
-        options:
-          items_per_page: 10
-          offset: 0
-      style:
-        type: default
-      row:
-        type: ui_patterns
-        options:
-          default_field_elements: 0
-          inline:
-            title: 0
-          separator: ''
-          hide_empty: 0
-          pattern: teaser
-          pattern_variant: default
-          pattern_mapping:
-            'views_row:title':
-              destination: title
-              weight: 0
-              plugin: views_row
-              source: title
+      title: Articles
       fields:
         title:
           id: title
           table: node_field_data
           field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
           entity_type: node
           entity_field: title
+          plugin_id: field
           label: ''
+          exclude: false
           alter:
             alter_text: false
             make_link: false
             absolute: false
-            trim: false
             word_boundary: false
             ellipsis: false
             strip_tags: false
+            trim: false
             html: false
-          hide_empty: false
-          empty_zero: false
-          settings:
-            link_to_entity: true
-          plugin_id: field
-          relationship: none
-          group_type: group
-          admin_label: ''
-          exclude: false
           element_type: ''
           element_class: ''
           element_label_type: ''
@@ -104,9 +53,13 @@ display:
           element_wrapper_class: ''
           element_default_classes: true
           empty: ''
+          hide_empty: false
+          empty_zero: false
           hide_alter_empty: true
           click_sort_column: value
           type: string
+          settings:
+            link_to_entity: true
           group_column: value
           group_columns: {  }
           group_rows: true
@@ -117,49 +70,116 @@ display:
           multi_type: separator
           separator: ', '
           field_api_classes: false
+      pager:
+        type: some
+        options:
+          offset: 0
+          items_per_page: 10
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      empty: {  }
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          order: DESC
+          expose:
+            label: ''
+          exposed: false
+          granularity: second
+      arguments: {  }
       filters:
         status:
-          value: '1'
+          id: status
           table: node_field_data
           field: status
-          plugin_id: boolean
           entity_type: node
           entity_field: status
-          id: status
+          plugin_id: boolean
+          value: '1'
+          group: 1
           expose:
             operator: ''
-          group: 1
         type:
           id: type
           table: node_field_data
           field: type
-          value:
-            article: article
           entity_type: node
           entity_field: type
           plugin_id: bundle
-      sorts:
-        created:
-          id: created
-          table: node_field_data
-          field: created
-          order: DESC
-          entity_type: node
-          entity_field: created
-          plugin_id: date
-          relationship: none
-          group_type: group
-          admin_label: ''
-          exposed: false
-          expose:
-            label: ''
-          granularity: second
-      title: Articles
+          value:
+            article: article
+      style:
+        type: pattern
+        options:
+          grouping:
+            -
+              field: title
+              rendered: true
+              rendered_strip: false
+          pattern: teaser_wrapper
+          pattern_mapping:
+            'view_style:title':
+              destination: title
+              weight: 0
+              plugin: view_style
+              source: title
+            'view_style:rows':
+              destination: content
+              weight: 1
+              plugin: view_style
+              source: rows
+          pattern_settings: {  }
+          pattern_variant: default
+      row:
+        type: ui_patterns
+        options:
+          default_field_elements: 0
+          inline:
+            title: 0
+          separator: ''
+          hide_empty: 0
+          pattern: teaser
+          pattern_variant: default
+          pattern_mapping:
+            'views_row:title':
+              destination: title
+              weight: 0
+              plugin: views_row
+              source: title
+      query:
+        type: views_query
+        options:
+          query_comment: ''
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_tags: {  }
+      relationships: {  }
       header: {  }
       footer: {  }
-      empty: {  }
-      relationships: {  }
-      arguments: {  }
       display_extenders: {  }
     cache_metadata:
       max-age: -1
@@ -170,9 +190,9 @@ display:
         - user.permissions
       tags: {  }
   page_1:
-    display_plugin: page
     id: page_1
     display_title: Page
+    display_plugin: page
     position: 1
     display_options:
       display_extenders: {  }
diff --git a/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/pattern-teaser-wrapper.html.twig b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/pattern-teaser-wrapper.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..6f577c167eb6c7336d3797684e1cc3251f500e43
--- /dev/null
+++ b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/pattern-teaser-wrapper.html.twig
@@ -0,0 +1,12 @@
+{#
+/**
+ * @file
+ * Test teaser wrapper pattern.
+ */
+#}
+{% if title %}
+<h2 class="teaser-wrapper-title">{{ title }}</h2>
+{% endif %}
+{% if content %}
+  <div class="teaser-wrapper-content">{{ content }}</div>
+{% endif %}
diff --git a/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/teaser_wrapper.ui_patterns.yml b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/teaser_wrapper.ui_patterns.yml
new file mode 100644
index 0000000000000000000000000000000000000000..95b392f168eb37dbd162706d587a30a0d0cfd42c
--- /dev/null
+++ b/modules/ui_patterns_views/tests/modules/ui_patterns_views_test/templates/teaser_wrapper.ui_patterns.yml
@@ -0,0 +1,16 @@
+teaser_wrapper:
+  label: "Teaser wrapper"
+  variants:
+    default:
+      label: "Default"
+    highlighted:
+      label: "Highlighted"
+  fields:
+    title:
+      type: "text"
+      label: "Title"
+      preview: "Title"
+    content:
+      type: "render"
+      label: "Content"
+      preview: "Content"
diff --git a/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsRenderTest.php b/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsRenderTest.php
index cea28e8f86e76e1ae0e19c4aeff79aa61294c730..f503feb328f948c3ab2fa73608b7670772a61004 100644
--- a/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsRenderTest.php
+++ b/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsRenderTest.php
@@ -56,6 +56,20 @@ class UiPatternsViewsRenderTest extends WebDriverTestBase {
 
     $this->drupalGet('/articles');
 
+    // Format.
+    // Assert correct variant suggestions.
+    $suggestions = [
+      'pattern-teaser-wrapper--variant-default.html.twig',
+      'pattern-teaser-wrapper.html.twig',
+    ];
+    foreach ($suggestions as $suggestion) {
+      $assert_session->responseContains($suggestion);
+    }
+
+    // Test field content is rendered in field group pattern.
+    $assert_session->elementContains('css', 'h2.teaser-wrapper-title', 'Test article');
+
+    // Row.
     // Assert correct variant suggestions.
     $suggestions = [
       'pattern-teaser--variant-default--views-row--articles--page-1.html.twig',
diff --git a/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsSettingsTest.php b/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsSettingsTest.php
index c01620290b876d6cda95f6318c90801c7e393a7c..f39169087e7a13042d6b9e932d3e3a55e116e2a4 100644
--- a/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsSettingsTest.php
+++ b/modules/ui_patterns_views/tests/src/FunctionalJavascript/UiPatternsViewsSettingsTest.php
@@ -8,7 +8,7 @@ use Drupal\views\Entity\View;
 /**
  * Test that UI Patterns Views display formatter can be properly configured.
  *
- * @group ui_patterns_field_group
+ * @group ui_patterns_views
  */
 class UiPatternsViewsSettingsTest extends WebDriverTestBase {
 
@@ -49,15 +49,27 @@ class UiPatternsViewsSettingsTest extends WebDriverTestBase {
     // Visit Articles views setting page.
     $this->drupalGet('/admin/structure/views/view/articles');
 
-    // Access row style settings.
+    // Access format settings.
+    $page->clickLink('Change settings for this format');
+    $assert_session->assertWaitOnAjaxRequest();
+
+    // Configure format.
+    $page->selectFieldOption('style_options[variants][teaser_wrapper]', 'Highlighted');
+    $page->selectFieldOption('style_options[pattern_mapping][teaser_wrapper][settings][view_style:rows][destination]', 'Title');
+
+    // Submit format settings.
+    $page->find('css', '.ui-dialog-buttonpane .form-actions')->pressButton('Apply');
+    $assert_session->assertWaitOnAjaxRequest();
+
+    // Access row settings.
     $page->clickLink('Change settings for this style');
     $assert_session->assertWaitOnAjaxRequest();
 
-    // Configure row style.
+    // Configure row.
     $page->selectFieldOption('Variant', 'Highlighted');
     $page->selectFieldOption('Destination for Content: Title', 'Description');
 
-    // Submit row style settings.
+    // Submit row settings.
     $page->find('css', '.ui-dialog-buttonpane .form-actions')->pressButton('Apply');
     $assert_session->assertWaitOnAjaxRequest();
 
@@ -65,16 +77,26 @@ class UiPatternsViewsSettingsTest extends WebDriverTestBase {
     $page->find('css', '#edit-actions')->pressButton('Save');
 
     $view = View::load('articles');
-    $settings = $view->getDisplay('default')['display_options']['row']['options'];
 
+    $style_settings = $view->getDisplay('default')['display_options']['style']['options'];
     // Assert settings values.
-    $this->assertEquals($settings['pattern'], 'teaser');
-    $this->assertEquals($settings['pattern_variant'], 'highlighted');
-
+    $this->assertEquals($style_settings['pattern'], 'teaser_wrapper');
+    $this->assertEquals($style_settings['pattern_variant'], 'highlighted');
     // Assert mappings.
-    $this->assertNotEmpty($settings['pattern_mapping'], "Pattern mapping is empty.");
-
-    $mapping = $settings['pattern_mapping'];
+    $this->assertNotEmpty($style_settings['pattern_mapping'], "Pattern mapping is empty.");
+    $mapping = $style_settings['pattern_mapping'];
+    $this->assertArrayHasKey('view_style:title', $mapping, 'Mapping not found.');
+    $this->assertEquals($mapping['view_style:title']['destination'], 'title', "Mapping not valid.");
+    $this->assertArrayHasKey('view_style:rows', $mapping, 'Mapping not found.');
+    $this->assertEquals($mapping['view_style:rows']['destination'], 'title', "Mapping not valid.");
+
+    $row_settings = $view->getDisplay('default')['display_options']['row']['options'];
+    // Assert settings values.
+    $this->assertEquals($row_settings['pattern'], 'teaser');
+    $this->assertEquals($row_settings['pattern_variant'], 'highlighted');
+    // Assert mappings.
+    $this->assertNotEmpty($row_settings['pattern_mapping'], "Pattern mapping is empty.");
+    $mapping = $row_settings['pattern_mapping'];
     $this->assertArrayHasKey('views_row:title', $mapping, 'Mapping not found.');
     $this->assertEquals($mapping['views_row:title']['destination'], 'description', "Mapping not valid.");
   }
diff --git a/modules/ui_patterns_views/ui_patterns_views.install b/modules/ui_patterns_views/ui_patterns_views.install
new file mode 100644
index 0000000000000000000000000000000000000000..3f22b69fc2ab097f6ebd1b50fb63126b2ab0c08c
--- /dev/null
+++ b/modules/ui_patterns_views/ui_patterns_views.install
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * @file
+ * Install and update functions for the ui_patterns_views module.
+ */
+
+declare(strict_types = 1);
+
+/**
+ * Implements hook_requirements().
+ */
+function ui_patterns_views_requirements($phase): array {
+  $requirements = [];
+  if ($phase === 'runtime') {
+    if (\Drupal::moduleHandler()->moduleExists('ui_patterns_views_style')) {
+      $requirements['ui_patterns_views'] = [
+        'title' => t('UI Patterns Views'),
+        'value' => t('<code>ui_patterns_views_style</code> module is enabled'),
+        'description' => t('This module is deprecated and its features are now provided by <code>ui_patterns_views</code>. It is recommended to uninstall it.'),
+        'severity' => REQUIREMENT_WARNING,
+      ];
+    }
+  }
+  return $requirements;
+}
+
+/**
+ * Migration from ui_patterns_views_style.
+ */
+ function ui_patterns_views_update_9101(): void {
+    if (!\Drupal::moduleHandler()->moduleExists('ui_patterns_views_style')) {
+      return;
+    }
+    $entityStorage = \Drupal::service('entity_type.manager')->getStorage('view');
+    $views = $entityStorage->loadMultiple();
+    foreach ($views as $view) {
+      $dependencies = $view->getDependencies();
+      if (!isset($dependencies['module'])) {
+        continue;
+      }
+      if (!in_array('ui_patterns_views_style', $dependencies['module'])) {
+        continue;
+      }
+      unset($dependencies['module']['ui_patterns_views_style']);
+      $dependencies['module'][] = 'ui_patterns_views';
+      $view->set("dependencies", $dependencies);
+      $view->save();
+    }
+    \Drupal::service('module_installer')->uninstall(['ui_patterns_views_style']);
+}
diff --git a/modules/ui_patterns_views/ui_patterns_views.module b/modules/ui_patterns_views/ui_patterns_views.module
index 58f0b0425dd49eb0251df05fda7ce71fe0bf5498..c33331b0e6d19ae90167e5c4675b11879cb7024f 100644
--- a/modules/ui_patterns_views/ui_patterns_views.module
+++ b/modules/ui_patterns_views/ui_patterns_views.module
@@ -13,7 +13,11 @@ use Drupal\ui_patterns\Element\PatternContext;
 function ui_patterns_views_theme() {
   return [
     'pattern_views_row' => [
-      'variables' => ['view' => NULL, 'options' => [], 'row' => NULL],
+      'variables' => [
+        'view' => NULL,
+        'options' => [],
+        'row' => NULL,
+      ],
     ],
   ];
 }
@@ -47,7 +51,7 @@ function template_preprocess_pattern_views_row(array &$variables) {
 
   $variables['pattern'] = [];
   if ($view->preview && !isset($view->element['#embed'])) {
-    \Drupal::messenger()->addWarning(t("Pattern Views row plugin does not support preview."));
+    \Drupal::messenger()->addWarning(t('Pattern Views row plugin does not support preview.'));
     $variables['pattern'] = ['#type' => 'status_messages'];
   }
   elseif (!empty($fields)) {
@@ -74,7 +78,7 @@ function template_preprocess_pattern_views_row(array &$variables) {
 function ui_patterns_views_ui_patterns_suggestions_alter(array &$suggestions, array $variables, PatternContext $context) {
   if ($context->isOfType('views_row')) {
     $hook = $variables['theme_hook_original'];
-    $variant = $variables["variant"] ?? '';
+    $variant = $variables['variant'] ?? '';
     $view_name = $context->getProperty('view_name');
     $display = $context->getProperty('display');
 
@@ -96,7 +100,7 @@ function ui_patterns_views_ui_patterns_suggestions_alter(array &$suggestions, ar
 function ui_patterns_views_ui_patterns_destination_suggestions_alter(array &$suggestions, array $variables, PatternContext $context) {
   if ($context->isOfType('views_row')) {
     $hook = $variables['theme_hook_original'];
-    $variant = $variables["variant"] ?? '';
+    $variant = $variables['variant'] ?? '';
     $view_name = $context->getProperty('view_name');
     $display = $context->getProperty('display');
     $pattern = $context->getProperty('pattern');
diff --git a/tests/src/Kernel/AbstractUiPatternsTest.php b/tests/src/Kernel/AbstractUiPatternsTest.php
index 24ecfe726cb5307f59c5fbbff7317de5a9ab2eea..32718cc7f7d708a140d0db7afa9bd7c4f9568d11 100644
--- a/tests/src/Kernel/AbstractUiPatternsTest.php
+++ b/tests/src/Kernel/AbstractUiPatternsTest.php
@@ -9,8 +9,6 @@ use Drupal\KernelTests\KernelTestBase;
  * Abstract base test class.
  *
  * @group ui_patterns
- *
- * @package Drupal\Tests\ui_patterns\Kernel
  */
 abstract class AbstractUiPatternsTest extends KernelTestBase {