diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
index 9e5f704a2f7..a221f1c493c 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
@@ -185,6 +185,10 @@ abstract class ListItemBase extends FieldItemBase implements OptionsProviderInte
'#default_value' => 0,
'#attributes' => ['class' => ['weight']],
];
+ // Disable the remove button if there is only one row in the table.
+ if ($max === 0) {
+ $element['allowed_values']['table'][0]['delete']['#attributes']['disabled'] = 'disabled';
+ }
if ($delta < count($allowed_values)) {
$query = \Drupal::entityQuery($entity_type_id)
->accessCheck(FALSE)
@@ -261,6 +265,10 @@ abstract class ListItemBase extends FieldItemBase implements OptionsProviderInte
$delta = $element['table']['#max_delta'];
$element['table'][$delta]['item']['#prefix'] = '
' . ($element['table'][$delta]['item']['#prefix'] ?? '');
$element['table'][$delta]['item']['#suffix'] = ($element['table'][$delta]['item']['#suffix'] ?? '') . '
';
+ // Enable the remove button for the first row if there are more rows.
+ if ($delta > 0 && isset($element['table'][0]['delete']['#attributes']['disabled']) && !isset($element['table'][0]['item']['key']['#attributes']['disabled'])) {
+ unset($element['table'][0]['delete']['#attributes']['disabled']);
+ }
$response = new AjaxResponse();
$response->addCommand(new InsertCommand(NULL, $element));
diff --git a/core/modules/options/tests/src/Functional/OptionsFieldUITest.php b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
index 93bbca1d094..f7d56397aa5 100644
--- a/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
+++ b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
@@ -454,8 +454,21 @@ class OptionsFieldUITest extends FieldTestBase {
$this->createOptionsField($field_type);
$page = $this->getSession()->getPage();
- // Try to proceed without entering any value.
$this->drupalGet($this->adminPath);
+ // Assert that the delete button for a single row is disabled.
+ $this->assertCount(1, $page->findAll('css', '#allowed-values-order tr.draggable'));
+ $delete_button_0 = $page->findById('remove_row_button__0');
+ $this->assertTrue($delete_button_0->hasAttribute('disabled'), 'Button is disabled');
+ $page->findButton('Add another item')->click();
+ // Assert that the delete button for the first row is enabled if there are
+ // more that one rows.
+ $this->assertCount(2, $page->findAll('css', '#allowed-values-order tr.draggable'));
+ $this->assertFalse($delete_button_0->hasAttribute('disabled'), 'Button is enabled');
+ // Delete a row.
+ $delete_button_0->click();
+ // Assert that the button is disabled again.
+ $this->assertTrue($delete_button_0->hasAttribute('disabled'), 'Button is disabled');
+ // Try to proceed without entering any value.
$page->findButton('Save field settings')->click();
if ($field_type == 'list_string') {