Repository: symfony/ux
Pull request #2587 (2025-02-21 18:48:07)

[LiveComponent] Fix default select value with preferred choices
| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| Issues        | -
| License       | MIT

When there are preferred_choices set for a choice type Symfony
renders them before the actual choices so the default value in the
browser will be the first value of the preferred choices.


smnandre: Thank you @1ed !

--- 

Thinking out loud here... I'm less and less enjoying this whole mecanism. 

I'm starting to wonder if we should not revert it..  instead of trying to decide PHP-side how the browsers behave 🤷‍♂️ 

Patch:
diff --git a/src/LiveComponent/src/ComponentWithFormTrait.php b/src/LiveComponent/src/ComponentWithFormTrait.php
index a25a2d1d..00c98419 100644
--- a/src/LiveComponent/src/ComponentWithFormTrait.php
+++ b/src/LiveComponent/src/ComponentWithFormTrait.php
@@ -288,7 +288,7 @@ trait ComponentWithFormTrait
                 && !$child->vars['multiple']                // is not multiple
                 && !\is_string($child->vars['placeholder'])  // has no placeholder (empty string is valid)
             ) {
-                $choices = $child->vars['choices'];
+                $choices = $child->vars['preferred_choices'] ?: $child->vars['choices']; // preferred_choices has precedence, as they rendered before regular choices
                 do {
                     $choice = $choices[array_key_first($choices)];
                     if (!$choice instanceof ChoiceGroupView) {


Test patch:
diff --git a/src/LiveComponent/tests/Fixtures/Form/FormWithManyDifferentFieldsType.php b/src/LiveComponent/tests/Fixtures/Form/FormWithManyDifferentFieldsType.php
index 59537991..bc3794a2 100644
--- a/src/LiveComponent/tests/Fixtures/Form/FormWithManyDifferentFieldsType.php
+++ b/src/LiveComponent/tests/Fixtures/Form/FormWithManyDifferentFieldsType.php
@@ -74,6 +74,38 @@ class FormWithManyDifferentFieldsType extends AbstractType
                     'foo' => 1,
                 ],
             ])
+            ->add('choice_required_with_preferred_choices_array', ChoiceType::class, [
+                'choices' => [
+                    'Bar Group' => [
+                        'Bar Label' => 'ok',
+                        'Foo Label' => 'foo_value',
+                    ],
+                    'foo' => 1,
+                ],
+                'preferred_choices' => ['foo_value'],
+            ])
+            ->add('choice_required_with_preferred_choices_callback', ChoiceType::class, [
+                'choices' => [
+                    'Bar Group' => [
+                        'Bar Label' => 'ok',
+                        'Foo Label' => 'foo_value',
+                    ],
+                    'foo' => 1,
+                ],
+                'preferred_choices' => function ($choice): bool {
+                    return is_int($choice);
+                },
+            ])
+            ->add('choice_required_with_empty_preferred_choices', ChoiceType::class, [
+                'choices' => [
+                    'Bar Group' => [
+                        'Bar Label' => 'ok',
+                        'Foo Label' => 'foo_value',
+                    ],
+                    'foo' => 1,
+                ],
+                'preferred_choices' => [],
+            ])
             ->add('choice_expanded', ChoiceType::class, [
                 'choices' => [
                     'foo' => 1,
diff --git a/src/LiveComponent/tests/Functional/Form/ComponentWithFormTest.php b/src/LiveComponent/tests/Functional/Form/ComponentWithFormTest.php
index bfbe477c..e0d72870 100644
--- a/src/LiveComponent/tests/Functional/Form/ComponentWithFormTest.php
+++ b/src/LiveComponent/tests/Functional/Form/ComponentWithFormTest.php
@@ -182,6 +182,9 @@ class ComponentWithFormTest extends KernelTestCase
             'choice_required_with_empty_placeholder' => '',
             'choice_required_without_placeholder' => '2',
             'choice_required_without_placeholder_and_choice_group' => 'ok',
+            'choice_required_with_preferred_choices_array' => 'foo_value',
+            'choice_required_with_preferred_choices_callback' => '1',
+            'choice_required_with_empty_preferred_choices' => 'ok',
             'choice_expanded' => '',
             'choice_multiple' => ['2'],
             'select_multiple' => ['2'],
diff --git a/src/LiveComponent/tests/Unit/Form/ComponentWithFormTest.php b/src/LiveComponent/tests/Unit/Form/ComponentWithFormTest.php
index 01941f10..93dcaa0e 100644
--- a/src/LiveComponent/tests/Unit/Form/ComponentWithFormTest.php
+++ b/src/LiveComponent/tests/Unit/Form/ComponentWithFormTest.php
@@ -49,6 +49,9 @@ class ComponentWithFormTest extends KernelTestCase
                 'choice_required_with_empty_placeholder' => '',
                 'choice_required_without_placeholder' => '2',
                 'choice_required_without_placeholder_and_choice_group' => 'ok',
+                'choice_required_with_preferred_choices_array' => 'foo_value',
+                'choice_required_with_preferred_choices_callback' => '1',
+                'choice_required_with_empty_preferred_choices' => 'ok',
                 'choice_expanded' => '',
                 'choice_multiple' => ['2'],
                 'select_multiple' => ['2'],