Problem/Motivation

When configuring UI pattern settings in the Layout Builder configuration form, elements that do not map to standard HTML input primitives natively (such as select and radios) fail to appear within their designated setting groups (e.g., "Spacing", "Advanced"). Instead, these elements appear un-grouped at the absolute top of the configuration sidebar.

Technical Root Cause:

The ui_patterns_settings module prepends \Drupal\ui_patterns_settings\Element\PatternSettingTypeBase::formGroupProcess to elements to set their #group property. However, it assumes that Drupal's Core group resolution will handle moving the elements into their containers.

The issue happens because select and radios element types do not have \Drupal\Core\Render\Element\RenderElementBase::processGroup present in their native #process array. Because they skip processGroup, they are never registered to $form_state->getGroups(), and therefore are not moved into the group container.

The Duplication Issue:

If one attempts to fix this by simply appending processGroup to elements missing it in ui_patterns_settings_element_info_alter(), the elements successfully appear inside the group wrapper but are also rendered a second time at the top of the sidebar. This occurs because Drupal's native preRenderGroup leverages Element::children(), which ignores the numerically keyed references created by processGroup. As a result, preRenderGroup fails to set #printed = TRUE on the root-level element, causing duplicate rendering.

Steps to reproduce

  1. Install Drupal 10/11 with ui_patterns_settings and Layout Builder UI integration.
  2. Create a pattern that defines a settings group (e.g. tab_spacing).
  3. Assign a setting of type select or radios to this group in the *.ui_patterns.yml.
  4. Attempt to configure a layout block using this pattern in Layout Builder.
  5. Observe that the setting element appears completely outside the "Spacing" group wrapper, usually glued to the top of the form.

Proposed resolution

  1. In ui_patterns_settings_element_info_alter(), ensure that processGroup is appended to the #process array parameter if it natively lacks it (acting as a fallback for select, radios, etc.).
  2. Create a custom pre-render method preRenderHideGroupMember inside \Drupal\ui_patterns_settings\Element\PatternSettings (implementing TrustedCallbackInterface to satisfy Drupal 10/11 security checks).
  3. Append this rendering callback within hook_element_info_alter() to selectively force #printed = TRUE on elements that belong to a group prior to root rendering, preventing the duplicate ghost elements.

Comments

duwid created an issue.