Repository: symfony/ux
Pull request #2744 (2025-05-16 16:42:01)

[LiveComponent] `LiveProp`: Pass the property name as second parameter of the `modifier` callback
supersedes #2652 


Patch:
diff --git a/src/LiveComponent/CHANGELOG.md b/src/LiveComponent/CHANGELOG.md
index 692612be..82a4a7a1 100644
--- a/src/LiveComponent/CHANGELOG.md
+++ b/src/LiveComponent/CHANGELOG.md
@@ -1,5 +1,9 @@
 # CHANGELOG
 
+## 2.26.0
+
+-   `LiveProp`: Pass the property name as second parameter of the `modifier` callable
+
 ## 2.25.0
 
 -   Add support for [Symfony UID](https://symfony.com/doc/current/components/uid.html) hydration/dehydration
diff --git a/src/LiveComponent/doc/index.rst b/src/LiveComponent/doc/index.rst
index 3ab3fdad..1ed48080 100644
--- a/src/LiveComponent/doc/index.rst
+++ b/src/LiveComponent/doc/index.rst
@@ -2625,6 +2625,47 @@ This way you can also use the component multiple times in the same page and avoi
     <twig:SearchModule alias="q1" />
     <twig:SearchModule alias="q2" />
 
+.. versionadded:: 2.26
+
+   The property name is passed into the modifier function since LiveComponents 2.26.
+
+The ``modifier`` function can also take the name of the property as a secondary parameter.
+It can be used to perform more generic operations inside of the modifier that can be re-used for multiple props::
+
+    abstract class AbstractSearchModule
+    {
+        #[LiveProp(writable: true, url: true, modifier: 'modifyQueryProp')]
+        public string $query = '';
+
+        protected string $urlPrefix = '';
+
+        public function modifyQueryProp(LiveProp $liveProp, string $propName): LiveProp
+        {
+            if ($this->urlPrefix) {
+                return $liveProp->withUrl(new UrlMapping(as: $this->urlPrefix.'-'.$propName));
+            }
+            return $liveProp;
+        }
+    }
+
+    #[AsLiveComponent]
+    class ImportantSearchModule extends AbstractSearchModule
+    {
+    }
+
+    #[AsLiveComponent]
+    class SecondarySearchModule extends AbstractSearchModule
+    {
+        protected string $urlPrefix = 'secondary';
+    }
+
+.. code-block:: html+twig
+
+    <twig:ImportantSearchModule />
+    <twig:SecondarySearchModule />
+
+The ``query`` value will appear in the URL like ``/search?query=my+important+query&secondary-query=my+secondary+query``.
+
 Validating the Query Parameter Values
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/src/LiveComponent/src/Metadata/LivePropMetadata.php b/src/LiveComponent/src/Metadata/LivePropMetadata.php
index b6a94b7f..5fe8c154 100644
--- a/src/LiveComponent/src/Metadata/LivePropMetadata.php
+++ b/src/LiveComponent/src/Metadata/LivePropMetadata.php
@@ -135,7 +135,7 @@ final class LivePropMetadata
             throw new \LogicException(\sprintf('Method "%s::%s()" given in LiveProp "modifier" does not exist.', $component::class, $modifier));
         }
 
-        $modifiedLiveProp = $component->{$modifier}($this->liveProp);
+        $modifiedLiveProp = $component->{$modifier}($this->liveProp, $this->getName());
         if (!$modifiedLiveProp instanceof LiveProp) {
             throw new \LogicException(\sprintf('Method "%s::%s()" should return an instance of "%s" (given: "%s").', $component::class, $modifier, LiveProp::class, get_debug_type($modifiedLiveProp)));
         }


Test patch:
diff --git a/src/LiveComponent/tests/Unit/Metadata/LivePropMetadataTest.php b/src/LiveComponent/tests/Unit/Metadata/LivePropMetadataTest.php
index bca2d262..b3ffd9f1 100644
--- a/src/LiveComponent/tests/Unit/Metadata/LivePropMetadataTest.php
+++ b/src/LiveComponent/tests/Unit/Metadata/LivePropMetadataTest.php
@@ -29,7 +29,7 @@ class LivePropMetadataTest extends TestCase
         $component
             ->expects($this->once())
             ->method('modifyProp')
-            ->with($liveProp)
+            ->with($liveProp, 'propWithModifier')
             ->willReturn($liveProp->withFieldName('customField'));
 
         $livePropMetadata = $livePropMetadata->withModifier($component);