Overview
See #3467972-13: Unable to save node article form — remove obsolete TwoTerribleTextAreasWidget + fix duplicate `XB:image` SDC.
components/image/image.component.yml was added long ago, in 795f4db30, on April 26, before DrupalCon Portland — see https://wimleers.com/xb-week-5.
Some would argue it is unnecessarily nested, and @pdureau certainly has done that at #3446722-29: Introduce an example set of representative SDC components; transition from "component list" to "component tree":
$refs resolution don't seem to work yet in Experience Builder, so the component was not fully tested, but the component template is surprising:
<img src="{{ image.src }}" alt="{{ image.alt }}" width="{{ image.width }}" height="{{ image.height }}"></img>
What is the purpose of this component?
- it has a single prop, also called "image", so the component looks like a meaningless wrapper around this single prop
- it doesn't use the expected
attributes object
- no HTML classes (and the component has no dedicated CSS), so no specific UI purpose
- it is nothing more than a rigid HTML element, like an image renderable but less powerful because with hardcoded attributes (so not compatible with lazy loading or any API working with images)
Am I missing something?
Proposed resolution
TBD
User interface changes
TBD
Comments
Comment #3
wim leers👋 @pdureau — time to finally respond in detail to what you wrote on August 1!
Why is that meaningless?
When is it appropriate to use nested key-value pairs?
Not being an SDC expert, I think the current structure of
components/image/image.component.ymlmakes sense: theimageproperty fully encapsulates all concerns/semantics of what "an image" constitutes.If this is expected, then why isn't this imposed by SDC? 🤔
Correct, this is meant to be one of the "elements" (see
1.1 Elementsin the product requirements).IOW: this is intended to be a building block in other components.
That's a good argument to add an
attributesproperty in this particular case, but why is that generically true?Comment #4
wim leersComment #5
pdureau commentedThanks Wim for creating this issue and give us the opportunity to discuss about those subjects.
attributes object
It is the other way around. Every component template has an
attributesobject automatically injected.It is good practice to use this already available
attributesobject in the template because:extra_classesarray of strings propHowever, I believe this
attributescan be even better by allowing#attributeskey alongside#props["attributes"], and I may create a Core issue as soon as UI Patterns 2.0 is released.Image component and image prop
Because the full component and its single prop are the exact same thing :
With:
It says something about the architecture: one of the 2 layers, the
imagecomponent or theimageprop, is superfluous here.If we remove the prop, we get that:
With:
But we can remove the component instead, as proposed in the next section.
HTML elements as SDC components
Indeed, we need HTML elements renderables which are lighter than components:
Oh wait, we have this already 😉
https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...
No need to create a SDC component for each HTML elements, like:
No need to create a generic HTML element as a SDC component with:
Because HTML elements are not UI components. They don't have a design system meaning. We don't want to have them in the component libraries, we don't want them to show in component selectors, we don't want to load the full SDC API to render them.
Not every renderable must become a SDC component. I know, it is tempting, with such a great hammer, everything looks like a nail.
HTML elements, Icons (see https://www.drupal.org/project/ui_icons ), Inline Templates, Plain Text... are renderables but not components. And we will discover more on our journey to design system implementations.
So, maybe Experience Builder needs to handle non-SDC renderables in slots. For example, a WYSIWYG for #markup;
Comment #6
wim leersTIL. But my question still stands, albeit differently: why doesn't SDC then not complain about this Twig template not printing the
attributesvariable at all?This is not the way @lauriii has been talking about "elements" (during https://wimleers.com/xb-week-5#chaos-origin). He's been referring to them as a carefully curated set of SDCs, tagged/categorized as "elements".
IOW: "elements" !== "HTML elements".
We need a WYSIWYG to be able to provide HTML markup that goes into a prop. See #3467959: SDC and code component props should be able to receive HTML, editable in formatted text fields+widgets — I bet you'll want to chime in on that issue too :)
Comment #7
wim leersWRT definition of "elements" — see discussion at #3455036: Clarify "components" vs "elements" vs "patterns", there's no definitive answer yet.
Comment #8
pdureau commentedSDC is currently not validating the component templates. It doesn't check used but undefined slots or props, it doesn't check defined but unused slots or props.
ui_patterns_devel module has a drush command to do such checks (still WIP but already useful). I hope it will be useful and appreciated by the SDC community.
OK. Do you have an example of such carefully curated set of SDCs, tagged/categorized as "elements"? Maybe experience_builder:image is not a good example, because this one is clearly an HTML element.
Of course I will add a comment on this issue ;)
I enjoy our conversation, but I am also surprised we (Experience Builder team & UI Suite team) have different understandings and opinions on those SDC fundamentals: what is a component? how to use it? how to chose between slots and props? and other topics...
I know Experience Builder is trying to build both a display builder (a better Layout Builder) and an UI components loader/manager (like UI Patterns 2), and I understand it is not an easy task. But I am also afraid the components management may be bent in some ways we may regret later, in order to comply with the current state and needs of the display builder.
Comment #9
wim leersI think that belongs in Drupal core! (Although I could see that the performance cost might be too high 😬)
No, not yet. 😭 This is something I've been asking @lauriii to clarify and formally document in #3455036: Clarify "components" vs "elements" vs "patterns".
Great concerns. I very strongly agree.
Two observations:
(FYI: the ADR + docs that were added last week in #3461490: Document the current JSON-based data model, and describe in an ADR finally formally document what the status quo is and describes the need minimum evolutions we'll need to meet all XB product requirements.)
Comment #10
kristen polThis was very educational!
For example, I didn't realize that attributes were injected as I saw them explicitly in XB components, e.g.
https://git.drupalcode.org/project/experience_builder/-/blob/0.x/compone...
Based on this, I'm assuming we can just remove them from our SDCs.
Comment #11
pdureau commentedIndeed, I would not recommend to add this to your component definitions:
Because this prop is injected automatically by SDC anyway.
But most importantly, because using a PHP namespace as a prop type is not JSON Schema compliant. It is an SDC quirk, a Drupalism, we need to get rid off.
Related issue, kind of: #3457874: HTML attributes as Twig mappings instead of PHP objects
Comment #12
kristen polThanks! Created followup for XB:
#3470575: Remove `attributes` prop from all SDCs in the Experience Builder module
and reopened ours for SDDS:
#3469525: Update SDDS SDCs attributes prop to align with XB
Comment #13
wim leers#11 + #12: wow, that means this is yet another thing that SDC in core should be doing differently/better. That pattern is literally all over Drupal core! 🤪
Responding in more detail over at #3470575: Remove `attributes` prop from all SDCs in the Experience Builder module — let's continue that there.
Comment #14
wim leers@pdureau detailed response at #3470575-7: Remove `attributes` prop from all SDCs in the Experience Builder module, looking forward to your feedback! 🤓🙏
Comment #15
lauriiiElements are ultimately built-in building blocks provided by the Experience Builder. These will be eventually used by the component to build components that would be exposed within the component library.
It seems that the confusion is likely arising from the fact that currently both elements, and components are defined using SDC and from that perspective they look alike. As argued by #5, there could be ways to define them outside of SDC but I'm not sure I understand why that would be required, so long as we can separate elements from components?
Even if they are both defined as SDC, they are different from UX perspective, and elements would not be stored as part of a component library. Currently the UX designs are separating the elements from the component library for this reason.
Many of the elements could be expressed as:
<{{ html_tag }}{{attributes}}>{{ content }}</{{ html_tag }}>Even if we do that, we need to define the html tags / attributes available somewhere so that we can optimize the UX for the specific element. For example, it may not make sense to show the background color or font family options for an image whereas it makes sense for a container. Also, images need to have a field for alt text whereas other elements don't.
Comment #16
ctrladelImages fall into the weird category of being both an element and a component. They should be individually placeable within slots or on a page but are also a fundamental building block of other components.
I've found this to be a good way to future proof component definitions, it appears like a meaningless wrapper until there's a need to add another prop that is not directly an attribute of the image.
Attributes has always felt like an SDC antipattern that was included only to ease the integration with Drupal. This image use case is a great example of how a Drupal render array ends up having significant undefined impacts on the rendering of the component. An image component schema that fully defines/handles all the various ways to render an image as an html element would be way better then relying on whatever is in the attributes object but would be challenging with how much of an image's format/style is currently done in Drupal's render layer.
This issue is also making me wonder if part of the scope of #3454519: [META] Support component types other than SDC, block, and code components should be allowing media(and other entities?) to be placed directly in XB using view modes.
Comment #17
wim leersInteresting! 🤔 I'll think about that some more… (this reminds me of the
block_contentblock plugin, which I've been thinking about in the context of #3475584: Add support for Blocks as Components.)Based on #15 and #16, I think this needs input from @pdureau.
💯 — it's where the SDC abstraction feels broken/wrong/in violation with itself.
Comment #18
lauriiiSorry for the late reply here! We don't have this experience fully designed (yet) but this was discussed on a high level as part of the IA exercise. The plan is to allow exactly this; allow images to be defined as props of components and as elements that could be placed in slots.
Because of that, for media, like videos, files, and images, there are elements inside the "Elements" group:
The "Dynamic Components" group includes a section that would allow inserting content directly using the entity view modes:
Next step is to design what the UX of inserting these would look like. That will likely be in ~3-4 months from now. In the meanwhile, there's some work around the image attributes in #3494545: [later phase] SDC must be able to specify minimum dimensions for a prop receiving an image.
Comment #19
wim leersThanks for following through so quickly on my ping this morning, @lauriii 🙏😊
Comment #20
wim leersFYI: the tangentially related #3501902: Adding the Image component results in a state considered invalid landed, which makes XB leap ahead of SDC on one front: XB supports SDCS providing a default image.
Updated the meta #3462705 at #3462705-43: [META] Missing features in SDC needed for XB.
Comment #21
wim leersRelated: @lauriii's #3535153-6: Regression from #3515646: small images are pixelated because they're scaled to 100% of the container.
Comment #23
wim leersAFAICT we did this in #3535453: Create an Image SDC that can be included by other SDCs? 😄
Comment #24
penyaskitoAside of whatever we need because of #3352063: Allow schema references in Single Directory Component prop schemas:
attributesis being used properly in the twig template of the image component.So yes, feeling like this can be closed now.
Comment #25
wim leersMarking RTBC — @lauriii also is an SDC expert, so let's have him have the final say.
Comment #26
lauriiiThis has been completed from my perspective – the image component looks good. There might be a follow-up discussion to be had on best practices regarding the use of attributes object.
Comment #28
wim leersGreat, thanks!