From bd5c998838fc4049d36ea0eec256452073516b0f Mon Sep 17 00:00:00 2001
From: just_like_good_vibes <mickael@meulle.com>
Date: Wed, 5 Mar 2025 10:49:01 +0100
Subject: [PATCH 1/4] new stuffs

---
 src/Element/ComponentElementBuilder.php            |  3 ++-
 src/Element/ComponentForm.php                      |  2 +-
 src/Element/ComponentSlotForm.php                  | 14 ++++++++++----
 .../Source/DerivableContextSourceBase.php          |  7 +++++--
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/Element/ComponentElementBuilder.php b/src/Element/ComponentElementBuilder.php
index 3471054d..37f7ccbe 100644
--- a/src/Element/ComponentElementBuilder.php
+++ b/src/Element/ComponentElementBuilder.php
@@ -183,7 +183,8 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
         continue;
       }
       $build = $source->alterComponent($build);
-      $source_value = $source->getValue($slot_prop_type);
+      $source_value = $source->getValue($slot_prop_type) ?? [];
+      \Drupal::moduleHandler()->alter('component_built', $source_value, $source_configuration);
       if (Element::isRenderArray($source_value)) {
         $build["#slots"][$slot_id][] = $this->isSingletonRenderArray($source_value) ? array_values($source_value)[0] : $source_value;
       }
diff --git a/src/Element/ComponentForm.php b/src/Element/ComponentForm.php
index b90623d7..eb440834 100644
--- a/src/Element/ComponentForm.php
+++ b/src/Element/ComponentForm.php
@@ -287,7 +287,7 @@ class ComponentForm extends ComponentFormBase {
       '#ajax_url' => $element['#ajax_url'] ?? NULL,
       '#access' => $element['#render_props'] ?? TRUE,
       '#default_value' => [
-        'props' => $element['#default_value']['props'],
+        'props' => $element['#default_value']['props'] ?? [],
       ],
     ];
   }
diff --git a/src/Element/ComponentSlotForm.php b/src/Element/ComponentSlotForm.php
index e06e6e85..fcc47856 100644
--- a/src/Element/ComponentSlotForm.php
+++ b/src/Element/ComponentSlotForm.php
@@ -149,10 +149,12 @@ class ComponentSlotForm extends ComponentFormBase {
       /** @var \Drupal\ui_patterns\PropTypePluginManager $prop_type_manager */
       $prop_type_manager = \Drupal::service("plugin.manager.ui_patterns_prop_type");
       $definition = [
-        'ui_patterns' => $prop_type_manager->createInstance('slot', []),
+        'ui_patterns' => [
+          "type_definition" => $prop_type_manager->createInstance('slot', []),
+        ],
       ];
     }
-    $wrapper_id = static::getElementId($element, 'ui-patterns-slot-' . $slot_id);
+    $wrapper_id = static::getElementId($element, 'ui-patterns-slot-wrapper-' . $slot_id);
     $element['#tree'] = TRUE;
     $element['#table_title'] = $element['#title'];
     $element['#title_in_component'] = $element['#title'];
@@ -162,7 +164,7 @@ class ComponentSlotForm extends ComponentFormBase {
       (!isset($element['#default_value']['sources']) || count($element['#default_value']['sources']) === 0)) {
       $element['add_more_button'] = static::buildAddSourceButton($element, $definition, $wrapper_id);
     }
-    $element['#prefix'] = '<div class="uip-slot" id="' . $wrapper_id . '">';
+    $element['#prefix'] = '<div id="' . $wrapper_id . '">';
     $element['#suffix'] = '</div>';
     return $element;
   }
@@ -398,10 +400,14 @@ class ComponentSlotForm extends ComponentFormBase {
     $form_state->setRebuild(TRUE);
     $returned = NestedArray::getValue($form, $parents);
     $response = new AjaxResponse();
+    $returned["#prefix"] = "";
+    $returned["#suffix"] = "";
     $response->addCommand(new HtmlCommand('#' . $wrapper_id, $returned));
     if (isset($triggering_element["#ui_patterns_slot_operation"]) && $triggering_element["#ui_patterns_slot_operation"] === "add") {
       $selector = "#" . $triggering_element["#id"];
-      $response->addCommand(new InvokeCommand($selector, "val", [""]));
+      if (!isset($returned['#cardinality_multiple']) || $returned['#cardinality_multiple'] !== FALSE) {
+        $response->addCommand(new InvokeCommand($selector, "val", [""]));
+      }
     }
     return $response;
   }
diff --git a/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php b/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
index 2ea0dbd8..8c036eec 100644
--- a/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
+++ b/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
@@ -240,7 +240,7 @@ abstract class DerivableContextSourceBase extends SourcePluginBase {
     ];
     $source_container = [
       '#type' => 'container',
-      '#attributes' => ["id" => $wrapper_id],
+      '#attributes' => ["id" => $wrapper_id, "class" => ["derivable-context-source-wrapper"]],
       '#tree' => TRUE,
     ];
     if (!$derivable_context || !array_key_exists($derivable_context, $derivableContexts)) {
@@ -259,7 +259,7 @@ abstract class DerivableContextSourceBase extends SourcePluginBase {
     /** @var array<string, mixed> $derivable_context_form */
     $derivable_context_form = &$form[$derivable_context];
     $derived_context = reset($derived_contexts);
-    $component_id = $derived_context["component_id"]->getContextValue();
+    $component_id = isset($derived_context["component_id"]) ? $derived_context["component_id"]->getContextValue() : NULL;
     $is_slot = $this->isSlot();
     // When option is within a group.
     $group_label = $this->getDerivableContextsOptionGroupLabel($options_derivable_contexts, $derivable_context);
@@ -297,6 +297,9 @@ abstract class DerivableContextSourceBase extends SourcePluginBase {
    */
   private function getSelectedDerivableContext(FormStateInterface $form_state, array $options_derivable_contexts) : ?string {
     $derivable_context = (string) ($this->getSetting('derivable_context') ?? '');
+    if (!$derivable_context) {
+      $derivable_context = $form_state->getValue('derivable_context') ?? NULL;
+    }
     // Validate the selected derivable context.
     if ($derivable_context && !isset($options_derivable_contexts[$derivable_context])) {
       // Reset value, or take the first one if only one is available.
-- 
GitLab


From f92131686bf1505b9b1afd74fcbe0342fbcc6c7a Mon Sep 17 00:00:00 2001
From: just_like_good_vibes <mickael@meulle.com>
Date: Wed, 5 Mar 2025 11:56:27 +0100
Subject: [PATCH 2/4] phpstan issue

---
 src/Element/ComponentElementBuilder.php | 4 +++-
 ui_patterns.services.yml                | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/Element/ComponentElementBuilder.php b/src/Element/ComponentElementBuilder.php
index 37f7ccbe..df90d820 100644
--- a/src/Element/ComponentElementBuilder.php
+++ b/src/Element/ComponentElementBuilder.php
@@ -15,6 +15,7 @@ use Drupal\ui_patterns\SourceInterface;
 use Drupal\ui_patterns\SourcePluginBase;
 use Drupal\ui_patterns\SourcePluginManager;
 use Psr\Log\LoggerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 
 /**
  * Component render element builder.
@@ -35,6 +36,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
     protected SourcePluginManager $sourcesManager,
     protected PropTypePluginManager $propTypeManager,
     protected ComponentPluginManager $componentPluginManager,
+    protected ModuleHandlerInterface $moduleHandler,
     protected LoggerInterface $logger,
   ) {
   }
@@ -184,7 +186,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
       }
       $build = $source->alterComponent($build);
       $source_value = $source->getValue($slot_prop_type) ?? [];
-      \Drupal::moduleHandler()->alter('component_built', $source_value, $source_configuration);
+      $this->moduleHandler->alter('component_built', $source_value, $source_configuration);
       if (Element::isRenderArray($source_value)) {
         $build["#slots"][$slot_id][] = $this->isSingletonRenderArray($source_value) ? array_values($source_value)[0] : $source_value;
       }
diff --git a/ui_patterns.services.yml b/ui_patterns.services.yml
index 2652c1f1..ac131fbe 100644
--- a/ui_patterns.services.yml
+++ b/ui_patterns.services.yml
@@ -46,6 +46,7 @@ services:
       - "@plugin.manager.ui_patterns_source"
       - "@plugin.manager.ui_patterns_prop_type"
       - "@plugin.manager.sdc"
+      - "@module_handler"
       - "@logger.channel.ui_patterns"
   ui_patterns.component_element_alter:
     class: Drupal\ui_patterns\Element\ComponentElementAlter
-- 
GitLab


From 9dbfa69c0f4d4fdf8ba470d2c1e5679f31d0e30c Mon Sep 17 00:00:00 2001
From: just_like_good_vibes <mickael@meulle.com>
Date: Mon, 10 Mar 2025 15:13:03 +0100
Subject: [PATCH 3/4] updated

---
 src/Element/ComponentElementBuilder.php               |  4 ++--
 .../UiPatterns/Source/DerivableContextSourceBase.php  |  1 +
 ui_patterns.api.php                                   | 11 +++++++++++
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/Element/ComponentElementBuilder.php b/src/Element/ComponentElementBuilder.php
index df90d820..2b2902a2 100644
--- a/src/Element/ComponentElementBuilder.php
+++ b/src/Element/ComponentElementBuilder.php
@@ -91,7 +91,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
       $build = $source->alterComponent($build);
       $prop_type = $definition['ui_patterns']['type_definition'];
       $data = $source->getValue($prop_type);
-
+      $this->moduleHandler->alter('ui_patterns_source_value', $data, $source);
       if (empty($data) && $prop_type->getPluginId() !== 'attributes') {
         // For JSON Schema validator, empty value is not the same as missing
         // value, and we want to prevent some of the prop types rules to be
@@ -186,7 +186,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
       }
       $build = $source->alterComponent($build);
       $source_value = $source->getValue($slot_prop_type) ?? [];
-      $this->moduleHandler->alter('component_built', $source_value, $source_configuration);
+      $this->moduleHandler->alter('ui_patterns_source_value', $source_value, $source);
       if (Element::isRenderArray($source_value)) {
         $build["#slots"][$slot_id][] = $this->isSingletonRenderArray($source_value) ? array_values($source_value)[0] : $source_value;
       }
diff --git a/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php b/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
index 8c036eec..07e67511 100644
--- a/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
+++ b/src/Plugin/UiPatterns/Source/DerivableContextSourceBase.php
@@ -254,6 +254,7 @@ abstract class DerivableContextSourceBase extends SourcePluginBase {
     $derived_contexts = $derivable_context_plugin->getDerivedContexts();
     $form[$derivable_context] = $source_container;
     if (count($derived_contexts) === 0) {
+      $form["source"] = $source_container;
       return $form;
     }
     /** @var array<string, mixed> $derivable_context_form */
diff --git a/ui_patterns.api.php b/ui_patterns.api.php
index bacffbaa..63d21121 100644
--- a/ui_patterns.api.php
+++ b/ui_patterns.api.php
@@ -16,3 +16,14 @@
 function hook_component_info_alter(array &$definitions) {
   $definitions['COMPONENT_ID']['slots']['slot_name']["title"] = 'demo';
 }
+
+/**
+ * Alter Hook for UI Patterns source values.
+ *
+ * @param mixed $value
+ *   Value produced by the source.
+ * @param \Drupal\ui_patterns\SourceInterface $source
+ *   The source object which has produced the value.
+ */
+function hook_ui_patterns_source_value_alter(mixed &$value, \Drupal\ui_patterns\SourceInterface $source) : void {
+}
-- 
GitLab


From 68c695b0d31fd332cf5afc1d449227a5d4f7782a Mon Sep 17 00:00:00 2001
From: just_like_good_vibes <mickael@meulle.com>
Date: Mon, 10 Mar 2025 15:16:56 +0100
Subject: [PATCH 4/4] fixed PHPMD warning

---
 ui_patterns.api.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ui_patterns.api.php b/ui_patterns.api.php
index 63d21121..17504cf6 100644
--- a/ui_patterns.api.php
+++ b/ui_patterns.api.php
@@ -24,6 +24,8 @@ function hook_component_info_alter(array &$definitions) {
  *   Value produced by the source.
  * @param \Drupal\ui_patterns\SourceInterface $source
  *   The source object which has produced the value.
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  */
 function hook_ui_patterns_source_value_alter(mixed &$value, \Drupal\ui_patterns\SourceInterface $source) : void {
 }
-- 
GitLab