Problem/Motivation
ComponentForm has 2 issues:
- it is complicated UX
- it is sometimes slow
They are already addressed:
- UX with issues like #3525836: [2.0.5] Improve context switching UX and the experimental
ui_patterns_uimodule - performance with the current investigation from Mikael & Christian about internal logic
But there is another change we can do which will help on both subjects.
Proposed resolution
Today, when we load ComponentForm, the source selectors are populated for every props and slots, even if we will not edit them before saving the config.
Those selects are costly to build because we check source plugin availability and context matching for all of them.
Proposal: instead of populating the selects like today:

Let's generate a button with the selected/default source as a value:

When we click on it, an AJAX command replace the button with the expected select list.
| Comment | File | Size | Author |
|---|
Issue fork ui_patterns-3528205
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pdureau commentedComment #3
goz commentedIt's a performance solution, but, in my opinion, a bad thing for UX.
The idea is still great, may be we can find something to solve UX.
UX issue:
It's a button, we are not used to have a button in a form to display a select list / other options to configure switch a field. If i saw this button, i will don't know why it's here and what is its purpose. It's not intuitive.
Proposal:
1/ May be we could add some things with this button so we understand it's a default source and we can change it. May be adding an arrow inside the button, at right like a select list does ?
2/ Be more verbose, with text AND a button :
<span>Current source : URL</span><button>Change source</button>Comment #4
duaelfrI like goz's second idea and I think this could also work when nothing has been configured yet:
We would have to define a way to display a "summary" of the existing settings but this would be way more effective for performances because we would only need to load forms on demand. The downside is still usability because it's one more click in an UI that already needs a lot.
Comment #5
pdureau commentedThanks both for your feedbacks :)
We have this now #3519282: [2.0.4] Add PluginSettingsInterface::settingsSummary()
Comment #6
smovs commentedI like proposal #2 by @goz.
It would improve performance by reducing unnecessary load and avoiding the need to build the dropdown each time, which also helps users notice that there are more options for selection.
Comment #7
asherry commentedThis has definitely become more of an issue in our case. I'm using the components through ui_patterns_blocks in layout builder and the block edit form ends up with a load time of around 10 seconds each time. Then each subsequent time you change the slot source it's another 10 seconds.
I get why the interface is difficult, this is a needle in a haystack. This is basically, "hey, select pretty much anything in your entire site to embed here".
The only way I've gotten through this is to implement a hook_ui_patterns_source_info_alter and remove all the field plugins but I still need some of them. I brought the definition total from 4k to 600 but it's still slow.
At the very least I think that the interface needs to handle entity fields as a series of dropdowns and only load the definitions after some sort of context is set first.
If there is anything I can help with please let me know.
Comment #8
pdureau commentedHello,
We have 3 big opportunities to improve performance of UI Patterns 2:
So, we need to find a solution which is good both for performance and for UX. I am proposing to shamelessly copying the UX of ECA forms:
So, to replace the current clunky UX with fieldsets and always visible sources selectors:

We can do something like that:
Advantages:
This UX proposal is for props only, there is already a ticket about slots UX: #3478643: UX of source selector for slots
Comment #9
pdureau commentedComment #12
just_like_good_vibesHello All, we are really progressing on this issue, and the performance gains seems real. Someone wants to check? @asherry ?
many thanks in advance,
Comment #13
just_like_good_vibesa first working proposition to review :)
Comment #14
pdureau commentedTest with UI Patterns Field Formatters
UI: some widget are cropped
Example: checkbox

UX: the name of the prop appears at the end of the prop form
We need to remove it.
UX: we need the source label before the settings summary
Not for the default widget.
UX proposal: move the button in the corner
Just a proposal:
Settings summary
Maybe not necessary part of the scope of the current ticket, but we will need to add and improve the implementation of
PluginSettingsInterface::settingsSummary().For example,
EntityLinksSourcewill need a label for the template and tell about absolute.It is particularly important for the context switchers:
entity_reference)entity_field)Which can display both the
::settingsSummary()of the present source and the::settingsSummary()of the selected source, recursively.Test with Display Builder
In progress
Test with UI Patterns UI
To check.
Comment #15
pdureau commentedTest with UI Patterns Field Formatters
UI: some
widget are cropped
✅ Checkbox is not cropped anymore in the main form

❌ but it is cropped in the modal now:
And sometimes there is an horizontal scrollbar. Are the modal dimensions constrained?
UX: the name of the prop appears at the end of the prop form
✅ Ok, removed.
UX: we need the source label before the settings summary
⚠️ it is added, but we need to add markup to organize the information here (no CSS needed):

UX proposal: move the button in the corner
⚠️ done (in the bottom end, instead of top end, but that's OK)
But:
.uip-prop-box summary + * .uip-source-selector-toggle--openinstead of.uip-prop-box summary + * .uip-source-selector-toggle?.uip-prop-box .uip-source-selector-toggleinstead.Settings summary
Maybe not necessary part of the scope of the current ticket, but we will need to add and improve the implementation of
PluginSettingsInterface::settingsSummary().It is particularly important for the context switcher which can display both the
::settingsSummary()of the present source and the::settingsSummary()of the selected source, recursively.✅ Some changes have already be done, but we can do a follow-up for more.
Modal title
Instead of "Source of {{ prop }}" (Example: "Source of URL"), can we have just "{{ Prop }}"? Because:
Test with Layout Builder
TODO
Test with Display Builder
In progress
Test with UI Patterns UI
To check.
Comment #16
pdureau commentedComment #17
just_like_good_vibesrebased, reworked, improved :)
Here is the whole picture of what is pushed, to ease the review.
Closed state:
- a prop loads only its saved source, nothing else. A source "widget" shows its form inline, for any other source, a summary is shown.
- the edit button (a pencil) sits in the box title. It is rendered server side, no JavaScript involved.
- summaries show the source label then its settings. Context switchers also show what they embed, as a nested list.
Open state:
- the pencil opens the prop form in a core dialog (Drupal.dialog). Drag, resize, Escape, theming: everything comes from core. Only 135 lines of JavaScript and 32 lines of CSS remain on our side.
- without JavaScript the same button opens the form inline, with a plain submit.
- the source select stays visible even with a single candidate, so a reopened chain shows all its levels.
Also:
- settingsSummary() added or completed for field formatter, path, views fields, menu, checkbox and textarea list, with a shared truncation "helper" method in SourcePluginBase.
- the label_map element is removed from field and views sources: the box title and the dialog title already name the prop.
to help the review :
- most of the diff is in ComponentFormBase (shared machinery) and ComponentPropForm (the two states open and close).
- wrapOrTitle() and addClosedSummaryAndButton() only exist to stay under the phpmd complexity threshold.
- slots are untouched. The follow-up issue about slots can reuse the base class machinery, and merging getSources() with getSourceDefinitions() could be one of its first step.
Tests: kernel tests for the two states, a Playwright test driving a full chain in the dialog, existing tests adapted.
Comment #18
just_like_good_vibesComment #19
pdureau commentedTest with UI Patterns Field Formatters
UI: some widget are cropped
✅ Checkbox is not cropped anymore in the main form
✅ Checkbox is not cropped anymore in the modal now
✅ No more horizontal bar
Maybe because we are nwo using the Core Modal API.
UX: we need the source label before the settings summary
✅ added
UX proposal: move the button in the corner
✅ moved in the details summary HTML element
⚠️ Too much spacing. Proposal
⚠️ You can use
/core/misc/icons/787878/cog.svginstead, like Field UI does.Settings summary
Implementation of
PluginSettingsInterface::settingsSummary()has been improved but not reviewed yet.It is particularly important for the context switcher which can display both the
::settingsSummary()of the present source and the::settingsSummary()of the selected source, recursively.Modal title
✅ Only the prop label
Test with Layout Builder
❌ the modal is not opening, the HTTP response look legit:
No JS error.
Test with Display Builder
❌ it opens a new page instead of a modal
Test with UI Patterns UI
To check.
Comment #20
pdureau commented(previous comment has been updated with the Layout Builder fail)
Comment #21
just_like_good_vibesReady for review, all comments addressed :)
Comment #22
pdureau commentedLook & feel
⚠️ Nearly perfect, we just need to add this in order to avoid some misalignment:
Settings summary
Implementation of
PluginSettingsInterface::settingsSummary()has been improved but not full reviewed. Let's merge like that and do some follow-ups if needed.Test with UI Patterns Field Formatters
✅ OK, works well.
Test with Layout Builder
The modal is not opening, the HTTP response look legit:
No JS error.
Weird: the prop disappear on click.
Test with Display Builder
Tested with #3622023: Behaviors are not attached on htmx swaps outside the builder root (side panels).
It is not always working:
Test with UI Patterns UI
To check.
Comment #23
pdureau commentedComment #24
just_like_good_vibesok, as we discussed, i have made some more changes :
- i added the code for the slots, originally planned for issue #3478643: UX of source selector for slots, but it is good to have it here .
- i updated the display builder fix in #3622023: Behaviors are not attached on htmx swaps outside the builder root (side panels) to ensure the new buttons get their ajax behavior at load
- i added more tests, in particular to check the appearance of the popup on the host plugins (field UI, views, ckeditor, LB...etc)
Comment #26
just_like_good_vibesthis is a big one :)
a follow-up issue to be made by pdureau (incl how to nicely display settingsSummary)