diff --git a/layout_paragraphs.module b/layout_paragraphs.module
index 8354b5278df2c8e502c56d08c32e0cc340514dda..ebdf26d81f3fa4dbf037b2806bb10eb0e36e8e53 100644
--- a/layout_paragraphs.module
+++ b/layout_paragraphs.module
@@ -59,13 +59,13 @@ function layout_paragraphs_theme() {
       'variables' => [
         'attributes' => [],
         'label' => NULL,
-        'edit_url' => NULL,
-        'delete_url' => NULL,
-        'dialog_options' => NULL,
+        'edit_attributes' => [],
+        'delete_attributes' => [],
       ],
     ],
     'layout_paragraphs_builder_component_menu' => [
       'variables' => [
+        'attributes' => [],
         'types' => NULL,
       ],
     ],
diff --git a/layout_paragraphs.routing.yml b/layout_paragraphs.routing.yml
index 3fd64783dfb1c89bb502f8c8b117adf6848659e0..8b13518228f135fe74e9c55dd26c7a371d43a0a9 100644
--- a/layout_paragraphs.routing.yml
+++ b/layout_paragraphs.routing.yml
@@ -25,13 +25,9 @@ layout_paragraphs.builder.formatter:
     _layout_paragraphs_builder_access: 'TRUE'
 
 layout_paragraphs.builder.choose_component:
-  path: '/layout-paragraphs-builder/{layout_paragraphs_layout}/choose-component/{sibling_uuid}/{placement}/{region}/{parent_uuid}'
+  path: '/layout-paragraphs-builder/{layout_paragraphs_layout}/choose-component'
   defaults:
-    _controller: '\Drupal\layout_paragraphs\Controller\ChooseComponentController::build'
-    region: 0
-    parent_uuid: 0
-    sibling_uuid: 0
-    placement: 0
+    _controller: '\Drupal\layout_paragraphs\Controller\ChooseComponentController::list'
   options:
     parameters:
       layout_paragraphs_layout:
@@ -50,36 +46,10 @@ layout_paragraphs.builder.edit_item:
   requirements:
     _layout_paragraphs_builder_access: 'TRUE'
 
-layout_paragraphs.builder.insert_sibling:
-  path: '/layout-paragraphs-builder/{layout_paragraphs_layout}/insert-sibling/{sibling_uuid}/{placement}/{paragraph_type}'
-  defaults:
-    _form: '\Drupal\layout_paragraphs\Form\InsertComponentSiblingForm'
-  options:
-    parameters:
-      layout_paragraphs_layout:
-        layout_paragraphs_layout_tempstore: TRUE
-      paragraph_type:
-        type: entity:paragraphs_type
-  requirements:
-    _layout_paragraphs_builder_access: 'TRUE'
-
 layout_paragraphs.builder.insert:
   path: '/layout-paragraphs-builder/{layout_paragraphs_layout}/insert-component/{paragraph_type}'
   defaults:
-    _form: '\Drupal\layout_paragraphs\Form\InsertComponentForm'
-  options:
-    parameters:
-      layout_paragraphs_layout:
-        layout_paragraphs_layout_tempstore: TRUE
-      paragraph_type:
-        type: entity:paragraphs_type
-  requirements:
-    _layout_paragraphs_builder_access: 'TRUE'
-
-layout_paragraphs.builder.insert_into_region:
-  path: '/layout-paragraphs-builder/{layout_paragraphs_layout}/insert-into-region/{parent_uuid}/{region}/{paragraph_type}'
-  defaults:
-    _form: '\Drupal\layout_paragraphs\Form\InsertComponentForm'
+    _controller: '\Drupal\layout_paragraphs\Controller\ComponentFormController::insertForm'
   options:
     parameters:
       layout_paragraphs_layout:
diff --git a/src/Controller/ChooseComponentController.php b/src/Controller/ChooseComponentController.php
index 9ae6a21a7dd340cfbc165d12502c503049d3493d..d5916b37fe2956799586f91ed7d2c1a6da8a2e0e 100644
--- a/src/Controller/ChooseComponentController.php
+++ b/src/Controller/ChooseComponentController.php
@@ -5,14 +5,15 @@ namespace Drupal\layout_paragraphs\Controller;
 use Drupal\Core\Url;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Ajax\AjaxHelperTrait;
-use Drupal\Component\Serialization\Json;
 use Drupal\Core\Controller\ControllerBase;
-use Drupal\layout_paragraphs\LayoutParagraphsLayout;
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Drupal\layout_paragraphs\LayoutParagraphsLayout;
 use Drupal\layout_paragraphs\LayoutParagraphsLayoutRefreshTrait;
 use Drupal\layout_paragraphs\Event\LayoutParagraphsAllowedTypesEvent;
+use Drupal\layout_paragraphs\DialogHelperTrait;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
  * ChooseComponentController controller class.
@@ -24,13 +25,17 @@ class ChooseComponentController extends ControllerBase {
 
   use AjaxHelperTrait;
   use LayoutParagraphsLayoutRefreshTrait;
+  use DialogHelperTrait;
 
   /**
    * Settings to pass to jQuery modal dialog.
    *
    * @var array
    */
-  protected $dialogOptions;
+  protected $dialogOptions = [
+    'modal' => TRUE,
+    'width' => '70%',
+  ];
 
   /**
    * The entity type bundle info service.
@@ -57,15 +62,6 @@ class ChooseComponentController extends ControllerBase {
   public function __construct(EntityTypeBundleInfoInterface $entity_type_bundle_info, EventDispatcherInterface $event_dispatcher) {
     $this->entityTypeBundleInfo = $entity_type_bundle_info;
     $this->eventDispatcher = $event_dispatcher;
-    $this->dialogOptions = [
-      'width' => '70%',
-      'minWidth' => 500,
-      'maxWidth' => 1000,
-      'draggable' => TRUE,
-      'classes' => [
-        'ui-dialog' => 'lpe-dialog',
-      ],
-    ];
   }
 
   /**
@@ -81,80 +77,50 @@ class ChooseComponentController extends ControllerBase {
   /**
    * Builds the component menu.
    *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The HTTP request.
    * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
    *   The layout paragraphs layout object.
-   * @param string $sibling_uuid
-   *   The uuid of the paragraph to insert content adjacent to.
-   * @param string $placement
-   *   Whether to insert the new component "before" or "after" the sibling.
-   * @param string $region
-   *   The region the new component should be inserted into.
-   * @param string $parent_uuid
-   *   The uuid of the parent component we are inserting into.
    *
    * @return array
    *   The build array.
    */
-  public function build(
-    LayoutParagraphsLayout $layout_paragraphs_layout,
-    $sibling_uuid = '',
-    $placement = '',
-    $region = '',
-    $parent_uuid = ''
-    ) {
+  public function list(Request $request, LayoutParagraphsLayout $layout_paragraphs_layout) {
 
+    $route_name = 'layout_paragraphs.builder.insert';
     $route_params = [
       'layout_paragraphs_layout' => $layout_paragraphs_layout->id(),
     ];
-    if ($region && $parent_uuid) {
-      $route_name = 'layout_paragraphs.builder.insert_into_region';
-      $route_params += [
-        'parent_uuid' => $parent_uuid,
-        'region' => $region,
-      ];
-    }
-    elseif ($sibling_uuid && $placement) {
-      $route_name = 'layout_paragraphs.builder.insert_sibling';
-      $route_params += [
-        'placement' => $placement,
-        'sibling_uuid' => $sibling_uuid,
-      ];
-      $component = $layout_paragraphs_layout->getComponentByUuid($sibling_uuid);
-      $parent_uuid = $component->getParentUuid();
-      $region = $component->getRegion();
-    }
-    else {
-      $route_name = 'layout_paragraphs.builder.insert';
-    }
-
+    $query_params = [
+      'parent_uuid' => $request->query->get('parent_uuid', NULL),
+      'region' => $request->query->get('region', NULL),
+      'sibling_uuid' => $request->query->get('sibling_uuid', NULL),
+      'placement' => $request->query->get('placement', NULL),
+    ];
+    $types = $this->getAllowedComponentTypes($layout_paragraphs_layout, $query_params['parent_uuid'], $query_params['region']);
     // If there is only one type to render,
     // return the component form instead of a list of links.
-    $types = $this->getAllowedComponentTypes($layout_paragraphs_layout, $parent_uuid, $region);
     if (count($types) === 1) {
       $type_name = key($types);
       $type = $this->entityTypeManager()->getStorage('paragraphs_type')->load($type_name);
-      switch ($route_name) {
-        case 'layout_paragraphs.builder.insert_into_region':
-          $response = $this->formBuilder()->getForm('\Drupal\layout_paragraphs\Form\InsertComponentForm', $layout_paragraphs_layout, $type, $parent_uuid, $region);
-          break;
-
-        case 'layout_paragraphs.builder.insert':
-          $response = $this->formBuilder()->getForm('\Drupal\layout_paragraphs\Form\InsertComponentForm', $layout_paragraphs_layout, $type);
-          break;
-
-        case 'layout_paragraphs.builder.insert_sibling':
-          $response = $this->formBuilder()->getForm('\Drupal\layout_paragraphs\Form\InsertComponentSiblingForm', $layout_paragraphs_layout, $type, $sibling_uuid, $placement);
-          break;
-      }
+      $response = $this->formBuilder->getForm(
+        '\Drupal\layout_paragraphs\Form\InsertComponentForm',
+        $layout_paragraphs_layout,
+        $type,
+        $query_params['parent_uuid'],
+        $query_params['region'],
+        $query_params['sibling_uuid'],
+        $query_params['placement']
+      );
       return $response;
     }
 
     foreach ($types as &$type) {
-      $type['url'] = Url::fromRoute($route_name, $route_params + ['paragraph_type' => $type['id']])->toString();
+      $url_route_params = $route_params + ['paragraph_type' => $type['id']];
+      $url_options = ['query' => $query_params];
+      $type['url'] = Url::fromRoute($route_name, $url_route_params, $url_options)->toString();
       $type['link_attributes'] = new Attribute([
         'class' => ['use-ajax'],
-        'data-dialog-type' => 'modal',
-        'data-dialog-options' => Json::encode($this->dialogOptions),
       ]);
     }
 
@@ -167,6 +133,9 @@ class ChooseComponentController extends ControllerBase {
     $component_menu = [
       '#title' => $this->t('Choose a component'),
       '#theme' => 'layout_paragraphs_builder_component_menu',
+      '#attributes' => [
+        'class' => ['lpb-component-list'],
+      ],
       '#types' => [
         'layout' => $section_components,
         'content' => $content_components,
diff --git a/src/Controller/ComponentFormController.php b/src/Controller/ComponentFormController.php
new file mode 100644
index 0000000000000000000000000000000000000000..06597b09a5830fb5e77708d4013126e862fb3172
--- /dev/null
+++ b/src/Controller/ComponentFormController.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\layout_paragraphs\Controller;
+
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\AjaxHelperTrait;
+use Drupal\Core\Ajax\OpenDialogCommand;
+use Drupal\Core\Controller\ControllerBase;
+use Symfony\Component\HttpFoundation\Request;
+use Drupal\paragraphs\ParagraphsTypeInterface;
+use Drupal\layout_paragraphs\LayoutParagraphsLayout;
+use Drupal\layout_paragraphs\DialogHelperTrait;
+
+/**
+ * Class definition for ComponentFormController.
+ */
+class ComponentFormController extends ControllerBase {
+
+  use AjaxHelperTrait;
+  use DialogHelperTrait;
+
+  /**
+   * The options to use for opening the dialog.
+   *
+   * @var array
+   */
+  protected $dialogOptions = [
+    'modal' => TRUE,
+    'width' => '70%',
+    'minWidth' => 500,
+    'maxWidth' => 1000,
+    'draggable' => TRUE,
+    'classes' => [
+      'ui-dialog' => 'lpe-dialog',
+    ],
+  ];
+
+  /**
+   * Responds with a component insert form.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request.
+   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
+   *   The layout paragraphs layout object.
+   * @param \Drupal\paragraphs\ParagraphsTypeInterface $paragraph_type
+   *   The Paragraph Type to insert.
+   *
+   * @return array|\Drupal\Core\Ajax\AjaxResponse
+   *   A build array or Ajax respone.
+   */
+  public function insertForm(Request $request, LayoutParagraphsLayout $layout_paragraphs_layout, ParagraphsTypeInterface $paragraph_type) {
+
+    $parent_uuid = $request->query->get('parent_uuid');
+    $region = $request->query->get('region');
+    $sibling_uuid = $request->query->get('sibling_uuid');
+    $placement = $request->query->get('placement');
+
+    $form = $this->formBuilder()->getForm('\Drupal\layout_paragraphs\Form\InsertComponentForm', $layout_paragraphs_layout, $paragraph_type, $parent_uuid, $region, $sibling_uuid, $placement);
+    return $this->openForm($form, $layout_paragraphs_layout);
+  }
+
+  /**
+   * Returns the form, with ajax if appropriate.
+   *
+   * @param array $form
+   *   The form.
+   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
+   *   The layout paragraphs layout object.
+   *
+   * @return array|AjaxResponse
+   *   The form or ajax response.
+   */
+  protected function openForm(array $form, LayoutParagraphsLayout $layout_paragraphs_layout) {
+    if ($this->isAjax()) {
+      $response = new AjaxResponse();
+      $selector = $this->dialogSelector($layout_paragraphs_layout);
+      $response->addCommand(new OpenDialogCommand($selector, $form['#title'], $form, $this->dialogOptions));
+      return $response;
+    }
+    return $form;
+  }
+
+}
diff --git a/src/DialogHelperTrait.php b/src/DialogHelperTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..bad7593f6d027b241811a592b1e173ce510eb0a5
--- /dev/null
+++ b/src/DialogHelperTrait.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\layout_paragraphs;
+
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Ajax\CloseDialogCommand;
+
+/**
+ * Defines a dialog id helper trait.
+ */
+trait DialogHelperTrait {
+
+  /**
+   * Generates a dialog id for a given layout.
+   *
+   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
+   *   The layout paragraphs object.
+   *
+   * @return string
+   *   The id.
+   */
+  protected function dialogId(LayoutParagraphsLayout $layout) {
+    return Html::getId('lpb-dialog-' . $layout->id());
+  }
+
+  /**
+   * Generates a dialog selector for a given layout.
+   *
+   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
+   *   The layout paragraphs layout object.
+   *
+   * @return string
+   *   The dom selector for the dialog.
+   */
+  protected function dialogSelector(LayoutParagraphsLayout $layout) {
+    return '#' . $this->dialogId($layout);
+  }
+
+  /**
+   * Returns a CloseDialogComand with the correct selector.
+   *
+   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
+   *   The layout paragraphs layout object.
+   *
+   * @return \Drupal\Core\Ajax\CommandInterface
+   *   The close command.
+   */
+  protected function closeDialogCommand(LayoutParagraphsLayout $layout) {
+    return new CloseDialogCommand($this->dialogSelector($layout));
+  }
+
+}
diff --git a/src/Element/LayoutParagraphsBuilder.php b/src/Element/LayoutParagraphsBuilder.php
index eb1f890fd3e7c7052f633c835717ad23ef4bb9f0..63e9dfd3d8b86b40aa2e65430a7a2f61edf5f93e 100644
--- a/src/Element/LayoutParagraphsBuilder.php
+++ b/src/Element/LayoutParagraphsBuilder.php
@@ -2,23 +2,25 @@
 
 namespace Drupal\layout_paragraphs\Element;
 
-use Drupal\core\Url;
+use Drupal\Component\Serialization\Json;
+use Drupal\Core\Url;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Render\Renderer;
-use Drupal\Component\Serialization\Json;
 use Drupal\Core\Access\AccessResultAllowed;
-use Drupal\paragraphs\ParagraphInterface;
 use Drupal\Core\Layout\LayoutPluginManager;
 use Drupal\Core\Entity\EntityTypeBundleInfo;
 use Drupal\Core\Access\AccessResultForbidden;
 use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Render\Element\RenderElement;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\layout_paragraphs\LayoutParagraphsSection;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Template\Attribute;
+use Drupal\paragraphs\ParagraphInterface;
+use Drupal\layout_paragraphs\LayoutParagraphsSection;
 use Drupal\layout_paragraphs\LayoutParagraphsComponent;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
+use Drupal\layout_paragraphs\DialogHelperTrait;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines a render element for building the Layout Builder UI.
@@ -30,6 +32,8 @@ use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
  */
 class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryPluginInterface {
 
+  use DialogHelperTrait;
+
   /**
    * The layout paragraphs tempstore service.
    *
@@ -100,18 +104,6 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
    */
   protected $langcode;
 
-  /**
-   * The dialog options.
-   *
-   * @var array
-   */
-  protected $dialogOptions = [
-    'width' => 1200,
-    'height' => 500,
-    'modal' => TRUE,
-    'target' => 'lpb-component-menu',
-  ];
-
   /**
    * {@inheritDoc}
    */
@@ -283,27 +275,52 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
 
     $url_params = [
       'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
+    ];
+    $query_params = [
       'sibling_uuid' => $entity->uuid(),
     ];
 
     if ($this->editAccess($entity)) {
-      $edit_url = Url::fromRoute('layout_paragraphs.builder.edit_item', [
-        'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
-        'component_uuid' => $entity->uuid(),
+      $edit_attributes = new Attribute([
+        'href' => Url::fromRoute('layout_paragraphs.builder.edit_item', [
+          'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
+          'component_uuid' => $entity->uuid(),
+        ])->toString(),
+        'class' => [
+          'lpb-edit',
+          'use-ajax',
+        ],
+        'data-dialog-type' => 'dialog',
+        'data-dialog-options' => Json::encode([
+          'width' => '70%',
+          'modal' => TRUE,
+          'target' => $this->dialogId($this->layoutParagraphsLayout),
+        ]),
       ]);
     }
     else {
-      $edit_url = '';
+      $edit_attributes = [];
     }
 
     if ($this->deleteAccess($entity)) {
-      $delete_url = Url::fromRoute('layout_paragraphs.builder.delete_item', [
-        'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
-        'component_uuid' => $entity->uuid(),
+      $delete_attributes = new Attribute([
+        'href' => Url::fromRoute('layout_paragraphs.builder.delete_item', [
+          'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
+          'component_uuid' => $entity->uuid(),
+        ])->toString(),
+        'class' => [
+          'lpb-delete',
+          'use-ajax',
+        ],
+        'data-dialog-type' => 'dialog',
+        'data-dialog-options' => Json::encode([
+          'modal' => TRUE,
+          'target' => $this->dialogId($this->layoutParagraphsLayout),
+        ]),
       ]);
     }
     else {
-      $delete_url = '';
+      $delete_attributes = [];
     }
 
     $build['controls'] = [
@@ -314,9 +331,8 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
         ],
       ],
       '#label' => $entity->getParagraphType()->label,
-      '#edit_url' => $edit_url,
-      '#delete_url' => $delete_url,
-      '#dialog_options' => Json::encode($this->dialogOptions),
+      '#edit_attributes' => $edit_attributes,
+      '#delete_attributes' => $delete_attributes,
       '#weight' => -10001,
     ];
     if ($component->isLayout()) {
@@ -325,12 +341,12 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
 
     if ($this->createAccess()) {
       if (!$component->getParentUuid() && $this->layoutParagraphsLayout->getSetting('require_layouts')) {
-        $build['insert_before'] = $this->insertSectionButton($url_params + ['placement' => 'before'], -10000, ['before']);
-        $build['insert_after'] = $this->insertSectionButton($url_params + ['placement' => 'after'], 10000, ['after']);
+        $build['insert_before'] = $this->insertSectionButton($url_params, $query_params + ['placement' => 'before'], -10000, ['before']);
+        $build['insert_after'] = $this->insertSectionButton($url_params, $query_params + ['placement' => 'after'], 10000, ['after']);
       }
       else {
-        $build['insert_before'] = $this->insertComponentButton($url_params + ['placement' => 'before'], -10000, ['before']);
-        $build['insert_after'] = $this->insertComponentButton($url_params + ['placement' => 'after'], 10000, ['after']);
+        $build['insert_before'] = $this->insertComponentButton($url_params, $query_params + ['placement' => 'before'], -10000, ['before']);
+        $build['insert_after'] = $this->insertComponentButton($url_params, $query_params + ['placement' => 'after'], 10000, ['after']);
       }
     }
 
@@ -346,6 +362,8 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
       foreach ($region_names as $region_name) {
         $url_params = [
           'layout_paragraphs_layout' => $this->layoutParagraphsLayout->id(),
+        ];
+        $query_params = [
           'parent_uuid' => $entity->uuid(),
           'region' => $region_name,
         ];
@@ -359,7 +377,7 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
           ],
         ];
         if ($this->createAccess()) {
-          $build['regions'][$region_name]['insert_button'] = $this->insertComponentButton($url_params, 10000, ['center']);
+          $build['regions'][$region_name]['insert_button'] = $this->insertComponentButton($url_params, $query_params, 10000, ['center']);
         }
       }
     }
@@ -407,6 +425,8 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
    *
    * @param array[] $route_params
    *   The route parameters for the link.
+   * @param array[] $query_params
+   *   The query paramaters for the link.
    * @param int $weight
    *   The weight of the button element.
    * @param array[] $classes
@@ -415,17 +435,20 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
    * @return array
    *   The render array.
    */
-  protected function insertComponentButton(array $route_params = [], int $weight = 0, array $classes = []) {
+  protected function insertComponentButton(array $route_params = [], array $query_params = [], int $weight = 0, array $classes = []) {
     return [
       '#type' => 'link',
       '#title' => Markup::create('<span class="visually-hidden">' . $this->t('Choose component') . '</span>'),
       '#weight' => $weight,
       '#attributes' => [
         'class' => array_merge(['lpb-btn--add', 'use-ajax'], $classes),
-        'data-dialog-type' => 'modal',
-        'data-dialog-options' => Json::encode($this->dialogOptions),
+        'data-dialog-type' => 'dialog',
+        'data-dialog-options' => Json::encode([
+          'target' => $this->dialogId($this->layoutParagraphsLayout),
+          'modal' => TRUE,
+        ]),
       ],
-      '#url' => Url::fromRoute('layout_paragraphs.builder.choose_component', $route_params),
+      '#url' => Url::fromRoute('layout_paragraphs.builder.choose_component', $route_params, ['query' => $query_params]),
     ];
   }
 
@@ -434,6 +457,8 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
    *
    * @param array[] $route_params
    *   The route parameters for the link.
+   * @param array[] $query_params
+   *   The query parameters for the link.
    * @param int $weight
    *   The weight of the button element.
    * @param array[] $classes
@@ -442,16 +467,29 @@ class LayoutParagraphsBuilder extends RenderElement implements ContainerFactoryP
    * @return array
    *   The render array.
    */
-  protected function insertSectionButton(array $route_params = [], int $weight = 0, array $classes = []) {
+  protected function insertSectionButton(array $route_params = [], array $query_params = [], int $weight = 0, array $classes = []) {
     return [
       '#type' => 'link',
       '#title' => Markup::create($this->t('Add section')),
       '#attributes' => [
         'class' => array_merge(['lpb-btn', 'use-ajax'], $classes),
-        'data-dialog-type' => 'modal',
-        'data-dialog-options' => Json::encode($this->dialogOptions),
+        'data-dialog-type' => 'dialog',
+        'data-dialog-options' => Json::encode([
+          'modal' => TRUE,
+          'target' => $this->dialogId($this->layoutParagraphsLayout),
+        ]),
       ],
-      '#url' => Url::fromRoute('layout_paragraphs.builder.choose_component', $route_params),
+      '#url' => Url::fromRoute('layout_paragraphs.builder.choose_component', $route_params, ['query' => $query_params]),
+    ];
+  }
+
+  /**
+   * Returns an array of dialog options.
+   */
+  protected function dialogOptions() {
+    return [
+      'modal' => TRUE,
+      'target' => $this->dialogId($this->layoutParagraphsLayout),
     ];
   }
 
diff --git a/src/Form/ComponentFormBase.php b/src/Form/ComponentFormBase.php
index a77cff89219eb4928a71e12111d29361059d18c9..4514e48363b406b152bcb2fd80b95dece077aa4e 100644
--- a/src/Form/ComponentFormBase.php
+++ b/src/Form/ComponentFormBase.php
@@ -11,8 +11,8 @@ use Drupal\field_group\FormatterHelper;
 use Drupal\Core\Extension\ModuleHandler;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Ajax\AjaxFormHelperTrait;
+use Drupal\Core\Ajax\CloseDialogCommand;
 use Drupal\Core\Layout\LayoutPluginManager;
-use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -20,6 +20,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Drupal\layout_paragraphs\LayoutParagraphsLayoutRefreshTrait;
 use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
+use Drupal\layout_paragraphs\DialogHelperTrait;
 
 /**
  * Class LayoutParagraphsComponentFormBase.
@@ -30,6 +31,7 @@ abstract class ComponentFormBase extends FormBase {
 
   use AjaxFormHelperTrait;
   use LayoutParagraphsLayoutRefreshTrait;
+  use DialogHelperTrait;
 
   /**
    * The tempstore service.
@@ -369,7 +371,7 @@ abstract class ComponentFormBase extends FormBase {
    */
   public function cancel(array &$form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
-    $response->addCommand(new CloseModalDialogCommand());
+    $this->ajaxCloseForm($response);
     return $response;
   }
 
@@ -385,6 +387,17 @@ abstract class ComponentFormBase extends FormBase {
     return AccessResult::allowed();
   }
 
+  /**
+   * Closes the form with ajax.
+   *
+   * @param \Drupal\Core\Ajax\AjaxResponse $response
+   *   The ajax response.
+   */
+  protected function ajaxCloseForm(AjaxResponse &$response) {
+    $selector = $this->dialogSelector($this->layoutParagraphsLayout);
+    $response->addCommand(new CloseDialogCommand($selector));
+  }
+
   /**
    * Renders a single Layout Paragraphs Layout paragraph entity.
    *
diff --git a/src/Form/DeleteComponentForm.php b/src/Form/DeleteComponentForm.php
index d90c3896cc99e8f551b3b0ded81f78a9142b98af..11e4811e5b5cd483173d201dcf9fa2ba6eff984d 100644
--- a/src/Form/DeleteComponentForm.php
+++ b/src/Form/DeleteComponentForm.php
@@ -5,11 +5,12 @@ namespace Drupal\layout_paragraphs\Form;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\RemoveCommand;
+use Drupal\Core\Ajax\CloseDialogCommand;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Ajax\CloseModalDialogCommand;
+use Drupal\layout_paragraphs\DialogHelperTrait;
 use Drupal\layout_paragraphs\LayoutParagraphsLayout;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\layout_paragraphs\LayoutParagraphsLayoutRefreshTrait;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class DeleteComponentForm.
@@ -17,6 +18,7 @@ use Drupal\layout_paragraphs\LayoutParagraphsLayoutRefreshTrait;
 class DeleteComponentForm extends FormBase {
 
   use LayoutParagraphsLayoutRefreshTrait;
+  use DialogHelperTrait;
 
   /**
    * The layout paragraphs layout tempstore.
@@ -107,7 +109,7 @@ class DeleteComponentForm extends FormBase {
    */
   public function deleteComponent(array $form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
-    $response->addCommand(new CloseModalDialogCommand());
+    $response->addCommand(new CloseDialogCommand($this->dialogSelector($this->layoutParagraphsLayout)));
 
     if ($this->needsRefresh()) {
       return $this->refreshLayout($response);
@@ -127,7 +129,7 @@ class DeleteComponentForm extends FormBase {
    */
   public function closeForm(array $form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
-    $response->addCommand(new CloseModalDialogCommand());
+    $response->addCommand($this->closeDialogCommand($this->layoutParagraphsLayout));
     return $response;
   }
 
diff --git a/src/Form/EditComponentForm.php b/src/Form/EditComponentForm.php
index 791ee0d4a0ccbbbea482b2bd2cc8bd669058f64a..a30ecd832f604824acb8e240ec68c6deaf7da0f0 100644
--- a/src/Form/EditComponentForm.php
+++ b/src/Form/EditComponentForm.php
@@ -3,9 +3,7 @@
 namespace Drupal\layout_paragraphs\Form;
 
 use Drupal\Core\Ajax\AjaxResponse;
-use Drupal\Core\Form\SubformState;
 use Drupal\Core\Ajax\ReplaceCommand;
-use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\layout_paragraphs\LayoutParagraphsLayout;
 
@@ -63,7 +61,7 @@ class EditComponentForm extends ComponentFormBase {
   public function successfulAjaxSubmit(array $form, FormStateInterface $form_state) {
 
     $response = new AjaxResponse();
-    $response->addCommand(new CloseModalDialogCommand());
+    $this->ajaxCloseForm($response);
     if ($this->needsRefresh()) {
       return $this->refreshLayout($response);
     }
diff --git a/src/Form/InsertComponentForm.php b/src/Form/InsertComponentForm.php
index 91a0bb923b770f06dec70e7d17a9f35f00bce67a..c4e926da162c43ec1b70a502fc6096a99bcb028b 100644
--- a/src/Form/InsertComponentForm.php
+++ b/src/Form/InsertComponentForm.php
@@ -7,7 +7,6 @@ use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\AppendCommand;
 use Drupal\Core\Ajax\BeforeCommand;
 use Drupal\Core\Ajax\PrependCommand;
-use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\paragraphs\Entity\ParagraphsType;
 use Drupal\paragraphs\ParagraphsTypeInterface;
@@ -28,11 +27,13 @@ class InsertComponentForm extends ComponentFormBase {
   protected $domSelector;
 
   /**
-   * Whether to use "before", "after", or "append.".
+   * The jQuery insertion method to use for adding the new component.
+   *
+   * Must be "before", "after", "prepend", or "append.".
    *
    * @var string
    */
-  protected $method;
+  protected $method = 'prepend';
 
   /**
    * The uuid of the parent component / paragraph.
@@ -48,6 +49,22 @@ class InsertComponentForm extends ComponentFormBase {
    */
   protected $region;
 
+  /**
+   * Where to place the new component in relation to sibling.
+   *
+   * @var string
+   *   "before" or "after"
+   */
+  protected $placement;
+
+  /**
+   * The sibling component's uuid.
+   *
+   * @var string
+   *   The sibling component's uuid.
+   */
+  protected $siblingUuid;
+
   /**
    * {@inheritDoc}
    *
@@ -63,6 +80,10 @@ class InsertComponentForm extends ComponentFormBase {
    *   The parent component's uuid.
    * @param string $region
    *   The region to insert the new component into.
+   * @param string $sibling_uuid
+   *   The uuid of the sibling component.
+   * @param string $placement
+   *   Where to place the new component - either "before" or "after".
    */
   public function buildForm(
     array $form,
@@ -70,17 +91,26 @@ class InsertComponentForm extends ComponentFormBase {
     LayoutParagraphsLayout $layout_paragraphs_layout = NULL,
     ParagraphsType $paragraph_type = NULL,
     string $parent_uuid = NULL,
-    string $region = NULL
+    string $region = NULL,
+    string $sibling_uuid = NULL,
+    string $placement = NULL
     ) {
 
     $this->setLayoutParagraphsLayout($layout_paragraphs_layout);
     $this->paragraph = $this->newParagraph($paragraph_type);
-    $this->method = 'prepend';
+
     $this->parentUuid = $parent_uuid;
     $this->region = $region;
+    $this->siblingUuid = $sibling_uuid;
+    $this->placement = $placement;
+
     if ($this->parentUuid && $this->region) {
       $this->domSelector = '[data-region-uuid="' . $parent_uuid . '-' . $region . '"]';
     }
+    elseif ($this->siblingUuid && $this->placement) {
+      $this->domSelector = '[data-uuid="' . $sibling_uuid . '"]';
+      $this->method = $placement;
+    }
     else {
       $this->domSelector = '[data-lpb-id="' . $this->layoutParagraphsLayout->id() . '"]';
     }
@@ -103,7 +133,7 @@ class InsertComponentForm extends ComponentFormBase {
   public function successfulAjaxSubmit(array $form, FormStateInterface $form_state) {
 
     $response = new AjaxResponse();
-    $response->addCommand(new CloseModalDialogCommand());
+    $this->ajaxCloseForm($response);
     if ($this->needsRefresh()) {
       return $this->refreshLayout($response);
     }
@@ -142,7 +172,16 @@ class InsertComponentForm extends ComponentFormBase {
   }
 
   /**
-   * Inserts the new component into the layout, using the correct method.
+   * Inserts the new component into the layout.
+   *
+   * Determines the correct method based on provided values.
+   *
+   * - If parent uuid and region are provided, new component
+   *   is added to the specified region within the specified parent.
+   * - If sibling uuid and placement are provided, the new component
+   *   is added before or after the existing sibling.
+   * - If no parameters are added, the new component is simply added
+   *   to the layout at the root level.
    *
    * @return $this
    */
@@ -150,6 +189,17 @@ class InsertComponentForm extends ComponentFormBase {
     if ($this->parentUuid && $this->region) {
       $this->layoutParagraphsLayout->insertIntoRegion($this->parentUuid, $this->region, $this->paragraph);
     }
+    elseif ($this->siblingUuid && $this->placement) {
+      switch ($this->placement) {
+        case 'before':
+          $this->layoutParagraphsLayout->insertBeforeComponent($this->siblingUuid, $this->paragraph);
+          break;
+
+        case 'after':
+          $this->layoutParagraphsLayout->insertAfterComponent($this->siblingUuid, $this->paragraph);
+          break;
+      }
+    }
     else {
       $this->layoutParagraphsLayout->appendComponent($this->paragraph);
     }
diff --git a/src/Form/InsertComponentSiblingForm.php b/src/Form/InsertComponentSiblingForm.php
deleted file mode 100644
index 7da5d3bd4f9724d22e198e94b7ec37d1ef2e8633..0000000000000000000000000000000000000000
--- a/src/Form/InsertComponentSiblingForm.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-namespace Drupal\layout_paragraphs\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\paragraphs\Entity\ParagraphsType;
-use Drupal\layout_paragraphs\LayoutParagraphsLayout;
-
-/**
- * Class InsertComponentSiblingForm.
- *
- * Builds the form for inserting a sibling component.
- */
-class InsertComponentSiblingForm extends InsertComponentForm {
-
-  /**
-   * Where to place the new component in relation to sibling.
-   *
-   * @var string
-   *   "before" or "after"
-   */
-  protected $placement;
-
-  /**
-   * The sibling component's uuid.
-   *
-   * @var string
-   *   The sibling component's uuid.
-   */
-  protected $siblingUuid;
-
-  /**
-   * {@inheritDoc}
-   *
-   * @param array $form
-   *   The form array.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state object.
-   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
-   *   The layout paragraphs layout object.
-   * @param \Drupal\paragraphs\Entity\ParagraphsType $paragraph_type
-   *   The paragraph type.
-   * @param string $sibling_uuid
-   *   The uuid of the sibling component.
-   * @param string $placement
-   *   Where to place the new component - either "before" or "after".
-   */
-  public function buildForm(
-    array $form,
-    FormStateInterface $form_state,
-    LayoutParagraphsLayout $layout_paragraphs_layout = NULL,
-    ParagraphsType $paragraph_type = NULL,
-    string $sibling_uuid = NULL,
-    string $placement = NULL
-    ) {
-
-    $this->setLayoutParagraphsLayout($layout_paragraphs_layout);
-    $this->paragraph = $this->newParagraph($paragraph_type);
-    $this->method = $placement;
-    $this->domSelector = '[data-uuid="' . $sibling_uuid . '"]';
-    $this->placement = $placement;
-    $this->siblingUuid = $sibling_uuid;
-
-    return $this->buildComponentForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  protected function insertComponent() {
-    switch ($this->placement) {
-      case 'before':
-        $this->layoutParagraphsLayout->insertBeforeComponent($this->siblingUuid, $this->paragraph);
-        break;
-
-      case 'after':
-        $this->layoutParagraphsLayout->insertAfterComponent($this->siblingUuid, $this->paragraph);
-        break;
-    }
-    return $this;
-  }
-
-}
diff --git a/templates/layout-paragraphs-builder-component-menu.html.twig b/templates/layout-paragraphs-builder-component-menu.html.twig
index 75c6eb2f7e70ccb4bc74359c343f4ba85221ccec..c161b46c134ded7bcd07839a0ab82691ed60c6b7 100644
--- a/templates/layout-paragraphs-builder-component-menu.html.twig
+++ b/templates/layout-paragraphs-builder-component-menu.html.twig
@@ -1,4 +1,4 @@
-<div class="lpb-component-list">
+<div{{ attributes }}>
   <h4 class="visually-hidden">{{ 'Add Item'|t }}</h4>
   <div class="lpb-component-list__search">
     <input class="lpb-component-list-search-input" type="text" placeholder="Filter items..." />
diff --git a/templates/layout-paragraphs-builder-controls.html.twig b/templates/layout-paragraphs-builder-controls.html.twig
index 868168dc1e915b2cb682678ff6cfd8a24931cf57..5f957b0542a26abcde022b67db386b284162fcb3 100644
--- a/templates/layout-paragraphs-builder-controls.html.twig
+++ b/templates/layout-paragraphs-builder-controls.html.twig
@@ -3,6 +3,6 @@
     <span class="lpb-controls-label">{{label}}</span>
     <a class="lpb-up" href="#move-up"><span>{{ 'Move Up'|t }}</span></a>
     <a class="lpb-down" href="#move-down"><span>{{ 'Move Down'|t }}</span></a>
-    {% if edit_url %}<a class="lpb-edit use-ajax" data-dialog-type="modal" data-dialog-options="{{ dialog_options }}" href="{{edit_url}}"><span>{{ 'Edit'|t }}</span></a>{% endif %}
-    {% if delete_url %}<a class="lpb-delete use-ajax"  data-dialog-type="modal" href="{{delete_url}}" data-lpb-confirm="{{ 'Really delete? There is no undo.'|t }}"><span>{{ 'Delete'|t }}</span></a>{% endif %}
+    {% if edit_attributes %}<a{{ edit_attributes }}><span>{{ 'Edit'|t }}</span></a>{% endif %}
+    {% if delete_attributes %}<a{{ delete_attributes }}><span>{{ 'Delete'|t }}</span></a>{% endif %}
   </div>