Did you ever switch a Drupal Form API element from "select" to "radios" and expect it would behave equally? You're wrong! Here's (sadly) why...
In our drowl_paragraphs module we wanted to switch a setting from "select" to "radios" to allow style preview:
<?php
$style_boxstyle_options = [];// [...]
$element['style']['style_boxstyle']['style_boxstyle'] = [ '#type' =--> 'select', '#title' => $this->t('Box style'), '#options' => $style_boxstyle_options, '#empty_option' => $this->t('- None -'), '#default_value' => isset($item->style_boxstyle) ? $item->style_boxstyle : '', '#description' => $this->t('Predefined styling of this container.'), ]; ?>
What I expected was, that it's a simple switch and both would behave indentially regarding their empty value. But while a "select" automatically adds a "None" option if
<?php
'#required' =--> FALSE ?>
to make it de-selectable, a radio doesn't add such an option. It even doesn't allow for
<?php
'#empty_option' =--> $this->t('- None -') // or '#empty_value' => NULL ?>
or similar. It simply has all radios unchecked by default and if you've checked a radio, you'll be lost for the future. So the result of my research which lead to to some interesting information here: https://www.drupal.org/project/drupal/issues/1381140 is: If you switch the Drupal Form Element "select" to "radios" you have to add the empty option yourself and it seems best to use an empty string as key and '#default_value':
<?php
$style_boxstyle_options = [// Add none option ("radios" FAPI doesn't provide that)
'' =--> $this->t('- None -') ]; // [...] $element['style']['style_boxstyle']['style_boxstyle'] = [ '#type' => 'radios', '#title' => $this->t('Box style'), '#options' => $style_boxstyle_options, '#required' => FALSE, '#default_value' => !empty($item->style_boxstyle) ? $item->style_boxstyle : '', '#description' => $this->t('Predefined styling of this container.'), ]; ?>