Add Single Directory Components as a new experimental module

Created on 9 February 2023, over 1 year ago
Updated 18 April 2023, about 1 year ago

Problem/Motivation

We want to add the concept of a component in Drupal core. See Single directory components in core Active for more details.

What do you mean by "component"?

In this context, a component is the combination of:

  • A regular Twig template.
  • Metadata describing the input data the template accepts (the *.component.yml file).
  • Optional JavaScript.
  • Optional Styles.

Examples of components

See the test modules and themes in the MR to see some examples of components. You can also take a look at the SDC Examples contrib module .

Proposed resolution

Let's add a new experimental module to Drupal core.

Remaining tasks

  • , and some other framework maintainers.
  • .
  • .
  • - Since we plan on this will going into core itself, there is no need to rename the module (plus there's no viable names)
  • - completed by @larowlan
  • Fixed in commit 27525e27
  • ???
  • Profit!

Validation from themers

We have worked with themers to validate the developer experience by having
them create their own single directory components

FAQs

User interface changes

No user interface changes.

API changes

No API changes, but new APIs introduced. (TDB: explain the new APIs)

Data model changes

No changes.

Release notes snippet

TBD.

Feature request
Status

Fixed

Version

10.1

Component
Theme 

Last updated 1 minute ago

Created by

e0ipso Can Picafort

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @e0ipso
  • @e0ipso opened merge request.
  • e0ipso Can Picafort

    Alright, I am leaving the issue summary alone for now. On to fixing the issues reported by DrupalCI now.

  • e0ipso Can Picafort

    I lied, one more tweak.

  • Status changed to Needs review over 1 year ago
  • e0ipso Can Picafort

    As expected, all my example CSS files are failing linting 😂. I will take a crack at this later.

  • Status changed to Needs work over 1 year ago
  • The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • 🇺🇸United States mglaman WI, USA

    My one concern is this adds a new syntax when Twig has something similar:

    {% include 'template.html' with {'foo': 'bar'} %}
    

    https://twig.symfony.com/doc/3.x/tags/include.html

    Could we get SDC to work with {% include %} instead of {{ include }}

  • e0ipso Can Picafort

    @mglaman we are of a same mind on this. SDC actually leverage all three official ways include, embed, and extends.

    1. https://twig.symfony.com/doc/3.x/tags/include.html
    2. https://twig.symfony.com/doc/3.x/tags/embed.html
    3. https://twig.symfony.com/doc/3.x/tags/extends.html

    Are there any docs in particular that gave you the impression otherwise? I can see that we need a few updates in the docs already.

  • 🇮🇳India rajesh_jha

    +1 from me!
    I will be able to find everything in directory.
    A Twig template that declares what renders on the page.
    A CSS file for the style
    A JS file that defines behavior of the component. All at one place.

  • 🇨🇦Canada xmacinfo Canada

    Amazing!

    I am looking forward to seeing a component that also loads its SVG files (or any image file format). For example, to help create buttons using SVG icons.

  • 🇺🇸United States mglaman WI, USA

    @e0ipso I'm referring to

        {{ include('sdc_examples:my-button', {
          text: 'Click Me',
          iconType: 'external'
        }) }}
    

    Or is another accepted version of the following, accepted by Twig, which I am not aware of

    {% include 'template.html' with {'foo': 'bar'} %}
    
  • e0ipso Can Picafort

    Ah yes. Both forms are supported in Twig, tag and function. Function is preferrable according to Tiwg docs, but both work.

  • 🇪🇸Spain idiaz.roncero Madrid

    Huge +1 to this.

    Efforts on this direction are to be found elsewhere on the Drupal community, from CL_components to Radix theme to Emulsify, Compony, etc..

    On a larger level, efforts towards a "component-based" approach to the front-end are also to be found on such popular modules as SFC, UI Patterns and more. Even if those modules have chosen a different approach, they might also benefit from the improvements introduced by this module.

    This speaks lengths about the growing consensus on the Drupal front-end community towards a component-based front-end.

    Also, this module would ease a common friction point on Drupal: how can modules propose its own theming layer while leaving room for the developers to adapt it to their needs without much hassle, tons of overrides, preprocess, etc.

    The fact that this would not be a rewrite or refactor of the exiting theming layer but an optional extension to it could ease adoption and avoid disruptions of current workflows (and it would also leave room for developers wanting to stay with the current system).

    So, again: +1 +1 +1 +1 +1

  • e0ipso Can Picafort

    Adding "Needs frontend framework manager review" tag, and "Needs framework manager review". I have pinged @bnjmnm, @lauriii and @ckrina for the front-end framework manager review. I am not sure who to ping in the framework manager capacity yet.

  • Status changed to Needs review over 1 year ago
  • e0ipso Can Picafort

    Tests are green now!

  • 🇺🇸United States bnjmnm Ann Arbor, MI

    I think theres no shortage of eveidence that SDC is pretty darn cool (and I'm inclined to agree). When it comes to core inclusion there are additional questions that need to be asked, and my hope is they are seen as clarifying questions and not resistance to SDC overall (I do find it appealing!);

    WILL THIS GET USED (What are the actual chances of widespread adoption?)

    Although this issue has a good amount followers, I have a concern that this won't get much adoption outside of e0ipso + people who know e0ipso, and perhaps a small number of people who see a panel on it at a Drupalcon, realize it could benefit an upcoming project and that project is scheduled soon enough that they remember the panel. For all I know there's sufficient evidence to the contrary and that will help!

    If this goes direct to core, we don't have any evidence of overall adoption to determine if it's worth the long term maintenance burden of adding it. SDC could introduce many scenarios where changes to the theme system have to account for standard and sdc. It could slow down theme-related improvements overall. This additional burden is reasonable if SDC has a good number of users making use of it, but I currently don't know what the changes of that are (to clarify, this isn't a doubt... I just don't know!). I want to avoid a QuickEdit situation where its presence adds all sorts of edge cases to core development despite there being very little actual use of it.

    It's quite possible this could be popular with the community provided the wider community is sufficiently aware that it exists/how it would benefit them/how to set it up. I'd me more inclined to +1 a proposal if it incorporated efforts to increase the likelihood of that. This concern is completely separate from SDC's merits as a feature. Unfortunately, evidence that something is a great new feature doesn't necessarily translate into adoption.

    IS THIS THE BEST OPTION (What specific pain points are addressed, and why is this the best way to address those?)

    The Drupal theming experience could certainly be improved, and SDC would provide some nice improvements. To justify an addition to core, it's important to assess why this is the ideal choice to address those problems. The merits of SDC are quite clear, there's no lack of evidence as to why SDC is a very cool thing. However, this proposal would benefit from an assesment why it's the approach worth pursuing when other theming-experience-improving options exist. It's quite possible that this is the ideal solution, but that won't be clear unless it's compared to other alternatives (or there's evidence that no alternatives exist).

  • 🇨🇦Canada xmacinfo Canada

    @bnjmnm: I agree with you. However, Drupal have experimental modules and SDC is targeted to be experimental. It's not all experimental that end up being popular, but at least it let the community gauge the usage of those experiments.

  • 🇺🇸United States mglaman WI, USA

    Drupal have experimental modules and SDC is targeted to be experimental.

    My argument against an experimental module is that they are bound to Drupal's release cycle – every six months. Contrib can release weekly to provide value and get feedback.

    https://www.drupal.org/project/sdc reports three sites using it. I'm well aware that the usage reports aren't great metrics since it requires update.module to be installed.

    A great example is this issue for SDC: https://www.drupal.org/project/sdc/issues/3346022 Allow different methods of discovery for SDC components Fixed . It would be hard to get feedback and quick iteration if this was locked into Drupal core.

    I think it's cool, but I don't think SDC is mature enough with enough adoption. But! Maybe getting it into Drupal core as an experimental module fixes this problem.

  • 🇬🇧United Kingdom jonathanshaw Stroud, UK

    I think the key reason for this to be in core is pointed at this quote in the IS:

    Projects that provide a different component solution like Compony, UI Suite, CL Components, and others, will see their different solution on this small part (the component definition) superseded by the new core standard. That is a good thing. UI Suite (for instance) can now leverage the new component solution, and not maintain its own.

    Significant contrib modules, and solutions particular to specific agencies or enterprise projects, are already "rolling their own" in this space.

    We need this in core so that everyone can stop developing their own standards and agree on a common spec. Existing projects are not going to want to go through the work of adapting to a slightly different approach, if that approach is only a contrib module and there's no confidence it's not the future-compatible core solution.

    Getting a foundation in core galvanises coherence in a whole ecosystem.

  • 🇺🇸United States dalemoore

    I hope to experiment with this soon. Definitely interested! I have yet to make a component/design system but it's on my radar to start on it for my organization. I think this would work better to start in contrib first to make sure there's enough interest in it. I don't have enough experience or knowledge yet (I haven't used Storybook but it looks awesome!) but tying a core system to something like Storybook that may go away could be tricky. Then again you have CMS like WP going all-in on React.

    I like that this system allows you to make the components through modules though. I wouldn't want them to only be possible in the theme. I'd rather be able to activate components one-by-one and have them re-usable across themes. But, still allow "the Drupal way" to have the theme override the module's component. From what I've read this does that?

  • e0ipso Can Picafort

    tying a core system to something like Storybook that may go away could be tricky.

    This may be a documentation issue, but there is absolutely nothing about Storybook in the SDC proposal or this MR.

  • e0ipso Can Picafort

    @mglaman in #31

    https://www.drupal.org/project/sdc reports three sites using it.

    This project was never intended for anyone to install, but a means for me to share code with Lauri as he did peer reviews. It should have stayed as a sandbox but I decided to promote it to avoid name-squatting. So, I would not give too much thought to that.

    A great example is this issue for SDC: https://www.drupal.org/project/sdc/issues/3346022 Allow different methods of discovery for SDC components Fixed . It would be hard to get feedback and quick iteration if this was locked into Drupal core.

    We addressed a lot of those questions in the effort for JSON:API by dealing with them first in JSON:API Extras. In fact most (if not all) of the new features added to JSON:API after core inclusion were ported from Extras after the necessary experimentation cycle. In my opinion, this is a pattern we might follow here.

    I think it's cool, but I don't think SDC is mature enough with enough adoption. But! Maybe getting it into Drupal core as an experimental module fixes this problem.

    SDC is the response to an old need (so the need is mature). CL Components has been tested in very high profile sites, and the custom solution that preceded CL Components was as well. So, in a way, SDC is not the brand new approach it seems to be. It is true that some key concepts evolved from CL Components for core inclusion, but none of the critical ones (mainly scope reduction for core maintainability).

  • e0ipso Can Picafort

    Added a small note on the FAQ based on recent feedback.

    Thanks for providing input! 🤩

  • e0ipso Can Picafort

    @bnjmnm in #29

    WILL THIS GET USED (What are the actual chances of widespread adoption?)

    This is impossible to answer. Popularity is, by nature, unpredictable (otherwise everything would be popular, therefore nothing would be). But I believe it can be argued.

    I have a concern that this won't get much adoption outside of e0ipso + people who know e0ipso

    This may be the first time someone has hinted that I might be popular! 😛 I blame Mike H. Now more seriously, this is a valid concern. Is there anything in particular the puts you in this train of thought?

    The way I see it is that we are taking the most popular pattern in existence in UI development, and formalizing it in core.

    I run out of ideas to check if they use components or not. To get back to your question, we cannot prove that bringing components into Drupal core will be popular, but we can prove that all (nearly all?) popular modern projects have them at their core.

    I want to avoid a QuickEdit situation where its presence adds all sorts of edge cases to core development despite there being very little actual use of it.

    I don't know much of the problems it caused, but QuickEdit was a complete paradigm change on editing content. SDC expands the current theme system capabilities, instead of forking them, so I don't anticipate such additional burden. SDC "only" relies on Twig, plugins, render arrays, and the libraries API, nothing exotic. In any case, let's be vigilant on this when we do the technical review.

  • 🇺🇸United States mherchel Gainesville, FL, US

    I personally don't have a shred of doubt that this SDC will be the defacto way to theme Drupal 3+ years down the line.

    WILL THIS GET USED?

    Education will help. I will be giving a session at DrupalCon Pittsburgh, as well as at various DrupalCons.

    The biggest education will be when we migrate components within Starterkit_theme, Olivero, Claro, as time permits and the use case makes sense.

    My argument against an experimental module is that they are bound to Drupal's release cycle – every six months. Contrib can release weekly to provide value and get feedback.

    Front-end developers will be more likely to use this when they know this is on track for inclusion in core. If there's doubt that this will go into core, there likely won't be widespread adoption because they could just continue to use CL Components, UI Patterns, or their home-rolled solutions.

    Note that the API is validated against CL Components, and we also had a meeting with the developers of UI Patterns to address any concerns.

    We need this in core so that everyone can stop developing their own standards and agree on a common spec. Existing projects are not going to want to go through the work of adapting to a slightly different approach, if that approach is only a contrib module and there's no confidence it's not the future-compatible core solution.

    Getting a foundation in core galvanises coherence in a whole ecosystem.

    This is the key point here, and I couldn't say it better myself.

    IS THIS THE BEST OPTION?

    There will always be better ways to do things. If we wait 2 years, we may have newer and better ideas. But doing so leaves Drupal with a difficult frontend developer experience. SDC is a remarkable improvement over the current paradigm of theming for many reasons (hence the interest from those that know).

    In the meantime, please see this section of Dries' DrupalCon Prague keynote:

    When you keep a bar as high as Drupal, perfect can become the enemy of good. Sometimes I see people become afraid of making mistakes. There's a lot of people that depend on Drupal. I think that fear can sometimes hold up important and faster progress. I think its important to recognize that fast progress can only be made when we're not afraid of making mistakes and when we have a culture that is accepting of that. - Dries

    Source at https://www.youtube.com/watch?list=PLpeDXSh4nHjRK_6I7HVLCw8k_ZTopYv5i&t=...

  • 🇬🇧United Kingdom dreamleaf

    +1 for trying to get this in as an experimental module.

    Standardisation

    As with every aspect of Drupal, there are many ways to achieve an end result, but that doesn't mean there shouldn't be strong, opinionated examples within Core of how to make the system more cohesive and standardised. We already have coding standards, and I see SDC much like "use 2 spaces instead of a tab" - there is a reason to do it that benefits the whole ecosystem.

    The concept of components is already heavily ingrained in Drupal, we have a block system that allows us to create custom blocks that are used sitewide, Paragraphs is used on over 200k sites (that are reporting... so many more) and there are countless other examples in use and in previous versions (Panels etc) that have sought to offer an organised approach to the component framework.

    What we don't currently have is a recommended and approved core concept of expressing this at the theme level, and this is the important part for me. If SDC or something like became "core", it solves the challenge of everyone having to devise their own way of implementing structure - although, they would still be free to do so if they wanted without breaking anything. So it's a win on all sides, with the only downside being that someone else may see a different approach as preferable and therefore think "their way" should be in core.

    Adoption

    As mentioned in other comments, education is key to adoption. Drupal is very good at providing developer docs, but not so great at the bringing people into the ecosystem/reasons why they should. I don't mean pandering to poach from other systems, but providing a simple, clear walkthrough of how and why we do certain things so people can make an informed decision and know what to expect before jumping in.
    We have to consider as well, that Drupal's long term future is dependent upon getting new blood as well as rewarding time-served contributors. There is nothing abnormal about the SDC approach in the wider landscape, a lot of the people who would use it will already expect there to be some kind of "Drupal Way", so if provided it just needs to be clearly delivered as part of the package.

    Why now?

    Introducing SDC would also tie in with other initiatives that are in the pipeline. The first one that springs to mind is the Recipes initiative. Having a standardised approach to that, which can then be easily altered/customised is essential to make that work. When I first heard about the recipes stuff, I had this initial thought that it would become dependency hell - relying on a specific theme or other functionality - SDC inclusion here would eliminate that doubt AND increase adoption levels of both SDC & Recipes.
    You could apply the same thinking to any contributed module that makes itself easier to work with. Which leads me to my final thought:

    Wider Ecosystem

    This issue mentions CLServer and CL Block as examples of further expansion within the ecosystem - and while not specifically relevant to this issue I thought I'd throw in a couple of thoughts.

    1) I love the concept of Storybook - and CL Servers integration is cool. But, I'm not inclined to want to introduce another tech stack to my Drupal work without substantial benefits. I can see how external integration can be an easier transition for larger agencies, but one of the reasons people love Drupal is because they aren't chasing the "newest love child framework". SDC doesn't have this mentality per se, but the education and adoption could be affected if people believe this is a subtle way to move towards those "proper" (included sarcastically) frontend frameworks.

    2) CL Block - Early days I know - but a casual glance at that gives me a little niggle. Using the UI to input twig code just feels wrong :) Maybe a better thought could be along the Patterns approach where you could create a suite of default components (not tied to specific fields) and then use that as a formatter for whatever is created. As I write this, I realise that I just explained "view modes" - so yeah, a view mode that picks up on a specific SDC default.
    My belief has always been that if you have to bring code into the front end, either the backend isn't working or you're providing a tool that is only usable by the few.

  • 🇳🇿New Zealand John Pitcairn

    one of the reasons people love Drupal is because they aren't chasing the "newest love child framework"

    This. For site builders who want to leverage more robust component encapsulation and sharing, wading through the competing frameworks-du-jour to decide on a lasting solution solution is daunting. Building on a core example would be a much friendlier entry point.

  • 🇪🇸Spain ckrina Barcelona

    WILL THIS GET USED
    We haven’t had major changes in how we do front-end since twig was introduced years ago. There has been improvements, but there hasn’t been a big and collective push forward on making life easier for front-ends. As a consequence, there isn’t a big Drupal front-end community anymore. We also almost don’t have new frontenders joining Drupal, specially not in the community. And having such a complicated ecosystem makes things really difficult for new folks unless you have a strong technical background. Just to add a simple JS file into a theme you need to know “the Drupal way”, which can frustrate a lot of people that is starting.

    IS THIS THE BEST OPTION
    As @e0ipso points, outside Drupal developing with components is not a discussion anymore. So IMHO the question here is not if we have to add components, but which one of the current solutions to work with components in Drupal we adopt.
    This one has a proven enough journey ( Component Libraries is the work behind SDC with +600 installs even without a stable release). Also, the team behind SDC has tried to work with UI Suite , one of the main Drupal ecosystems to work with components, to evaluate its integration 🌱 [2.0.x] Roadmap Active .
    SDC also learns from modern components approaches, which makes it suitable for core.
    As mentioned in several comments already, SDC postulates itself as an standardization. It’ll mean to share the lower layer to create components and all the other solutions will be able to build on top of that and get rid of some maintainability burden.

    As a final note, I’d like to point out that we don’t see this level of momentum in big front-end improvements everyday and it would be smart on our side to get the most of this opportunity.

  • 🇩🇪Germany geek-merlin Freiburg, Germany

    There are many good "Yes this is needed" points in the last responses, that i don't need to repeat. Thanks!

    I am NOT a FrontEnder, but i strongly beleive the frontend deserves something better that we have today, for Drupal to stay relevant and attract developers. So i don't think Drupal can afford delaying this much longer.

  • 🇫🇷France nod_ Lille

    Very much +1 to #41. Like ckrina pointed out, with ui pattern there is an ecosystem of 4k+ installs that could use this, and that's just what exists today, no telling what contrib will come up with tomorrow :)

  • 🇪🇸Spain idiaz.roncero Madrid

    So many great points were made, i just wanted to +1 to the overall idea that "the community is already expressing a need towards some kind of component standardization by developing a lot of competing / complementary solutions" as the main point favoring inclusion as an experimental module.

    Having a low-level, standardized way to deal with components and to be able to build upon would be a great step for Drupal.

    I imparted a DrupalCamp talk about componentization in Drupal past year. I talked with many front-end Drupal devs after and discovered that almost everybody was moving towards component-based solutions but that there was also a lack of (and longing for) common ground.

    Also, as ckrina pointed, the current status for front-end is driving many developers away. I am currently working as a Drupal teacher for several developers (in company, 1 to 1 education), some of them young, and the Drupal front-end is seen as frustrating and backwards by many of them, while the lack for drop-in components ("i just want to put my css, js and template logic together") is often cited.

  • 🇺🇸United States mglaman WI, USA

    I'll just update that I'm +1 from the feedback to my questions/concerns.

  • 🇺🇸United States markdorison

    This seems really compelling to me. +1

  • 🇺🇸United States guschilds

    I spent half of my ten years as a front-end Drupal developer wrestling with component-based development on client projects. Components were clearly the future, but the path forward was not.

    After that experience - and a few years with JS frameworks - SDC instantly makes perfect sense. It encapsulates exactly how components should work within a Drupal theme. It will also minimize the learning curve for the larger front end community. Teach them how to find the Drupal templates to include their components in and they'll be off to the races.

    I identify with #41 and agree that this would be the biggest improvement since Twig. I look forward to building with Single Directory Components one day!

  • 🇺🇸United States PCate

    An enthusiastic +1 for this. Everyone who has commented the past week already encapsulates my thoughts so I won't repeat them.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Updating issue summary after Slack conversation with @e0ipso and @lauriii.

    We're working really hard to get this in as BETA experimental for 10.1.0. To do this, I added to the remaining tasks above.

  • 🇺🇸United States ctrlADel North Carolina, USA

    I’m gonna start my response by quoting a comment I left in #3346022

    After spending some time in the code, if SDC were released today I'm not sure I'd adopt it. At the individual component level I would love to use them but if the only way to leverage components is through the current discovery/processing approach then I'm not sure. For a system that sits at the center of a site build it doesn't feel like I'd have enough control to make it my own and make changes to function in a way that works for my team or my clients.

    I’m as excited as everyone else about the potential of a standard component definition for the community to start converging on instead of all doing our own thing. My concern is that SDC contains a good definition of a component but is not a low level system, it’s a fully featured system built upon the approach used in cl_components, which has ~600 reported installs, not the approach in ui_patterns which has the much mentioned 4k+ users.

    The system introduced by SDC is opinionated, rigid, and with no affordances for contrib to build on top of it. Any attempt to add reasonable extension points has been met with a “we don’t think this is needed and are trying to limit API surface area” See:

    Allow different methods of discovery for SDC components Fixed
    Have a way to implement the a preprocess function per each SDC component (ideally in the same folder) Active
    🐛 Add alter hook and cache backend to component plugin manager for SDC Fixed

    The assurances that we’d be able to use a SDC Extras module to accomplish the iteration and maturing SDC needs is questionable in my mind, none of the three linked issues can be addressed without overriding/replacing significant pieces of the current SDC code.

    Specific areas of concern

    UI Patterns

    There has been much talk about how widely used UI Patterns is and how much SDC would benefit the ecosystem but as far as I could track down there hasn’t been any work to prove out SDC in it’s current state is compatible with UI Patterns. There is mention of potentially using it on the roadmap for 2.x 🌱 [2.0.x] Roadmap Active but that’s it.

    Template resolution

    SDC introduces a new way for resolving templates in twig
    {{ include('sdc_examples:my-button', {......}) }} that would not be available in other systems that use twig. This approach makes it so Drupal SDC components can’t be rendered in other php applications or in frontend tooling like Storybook. It wouldn’t be impossible to fix, there are paths to adding SDC’s template resolving to other applications but it creates a significant barrier. Twig.js for example doesn't have a documented way to add this https://github.com/twigjs/twig.js/wiki/Extending-twig.js. There is always the approach used by cl_components which is to connect Storybook to a live Drupal backend for rendering but that comes with its own set of drawbacks.

    Using twig’s native namespace functionality for template resolution would make SDC components much more compatible with other systems.

    Component discovery

    SDC only supports discovering components from *.component.yml files that are located in a module or theme but as mentioned earlier in the comments the concept of a component is not unique to Drupal and they can take many shapes in the wider frontend world. Even in Drupal we already have multiple ways to define components like UI Patterns, Component , Single File Components . Only supporting *.components.yml discovery is limiting and will make it difficult for other contrib modules to adopt SDC components. #3346022 aimed to address this by allowing anyone to add a component discovery method.

    A potential path forward?

    If we’re pushing hard to include the concept of a component in core, I think it'd be a good idea to split the component definition and component system parts of SDC into separate modules. This follows what was done with Layout API and Layout Builder which has proven to be a successful pattern since there are multiple widely used modules dependent on Layout API, namely Layout Builder and Layout Paragraphs. "SDC Component" containing the schema definition/validation could be included in core. Then contrib modules, including "SDC System", would be able to build on top of that truly low level system.

    Overall the definition and structure of a component in SDC is solid and I’d happily use it. The system and approaches that have been built up around that component definition I’m less confident in. The question for me is if I have to fight or significantly patch/override/replace parts of SDC to make it work for my project why not just build my own system?

  • e0ipso Can Picafort

    Added a note in the issue summary to explain why we are reluctant to allow the extensibility @ctrAltDel #51 requested.

  • 🇺🇸United States ctrlADel North Carolina, USA

    I took a pass at splitting the API and render parts of SDC into separate modules to see what it would look like. The result can be found here https://gitlab.com/ctrladel/sdc-component-api/-/tree/1.x/component_api.

    The result looks very similar to Layout API and Layout Builder. An API to define, validate, and discover a data structure and an implementation that makes the data structure actually usable in Drupal.

  • 🇺🇸United States ctrlADel North Carolina, USA

    We think it's not a good idea for core to support significant alterations to discovery and definition. This is because it increments the API surface of SDC and the maintenance of it in core. Additionally having disparate discovery and definition in different sites goes against the standarization goal. It will be difficult for a new front-end developer to understand their site when the documentation and examples look so different from what they see in their site. Contributed modules, however, can alter this behavior.

    The problem I see with this is that regardless of what we think best practice should be devs are going to tweak, change, and extend how SDC works because components sit at the very core of modern component based authoring experiences. The question is will they be able to do it in a way that is easy and supported or will they be stuck replacing parts of a core module? If different changes require replacing the same parts of SDC that also creates a compatibility problem in the contrib ecosystem.

    A few use cases I can think of:
    1. I have a design system from a client that contains components with twig/react/etc templates and ~75% of the definition SDC components need but the definitions are in a single json file, the missing 25% can be inferred from the 75%. How could a custom module create SDC components from that source?
    2. Some of the npm libraries I require via composer and install to the libraries directory have standard yaml SDC components in them. How do I get SDC to see them?
    3. I add a third party setting to my SDC components in a multisite environment that lists which sites a component should be available on. How do I filter the list of available components based on this prop?

    We also believe it's not a good idea to alter how a component is rendered. This is to avoid some of the current confusion that themers experience when several alters change how their template is rendered, or change their variables, etc. When that happens in different modules and base themes, finding your way around is quite hard. When everything can happen everywhere at any time, we can't have good documentation, we can't provide relatable examples, we can't give good support in Slack, newcomers can't state their problems correctly, ... We want to avoid that in components. The principle is that everything that affects a component, is in the component's folder.

    While I agree it'll be best practice to not preprocess components there's a valid argument that some times you just need to do the same preprocessing step across many components based on their values or context. Perhaps SDC shouldn't include a way to do preprocessing but it should include a way for contrib to add render preprocessing to SDC. With the current SDC approach how would a module add a render preprocessing system?

    Pushing all the preprocessing in to twig with custom functions/filters is also less than ideal for a few reasons

    • It's likely all the functions and filters will end up in one file or even worse spread across multiple modules and classes. Taking twig tweak's class as a sample of what could be needed on a project https://git.drupalcode.org/project/twig_tweak/-/blob/3.x/src/TwigTweakEx..., I wouldn't call it super approachable for a front end dev.
    • Pulling content directly in to twig via custom functions/filters has security, caching, and access control nuances that would make it a very hard feature for front end devs to use correctly. For example see #2660002: Allow explicit bubbling of cacheability metadata inside Twig template (when accessing data from instead of rendering render arrays)
    • Custom functions and filters reduce the portability of twig templates(especially if the custom functions load in additional content or processing logic via Drupal services). The custom functions/filters have to be stubbed or fully reimplemented to render the template in a system other then Drupal. I'm mainly thinking if you're trying to render the template in a js framework or Storybook using something like twig.js.
  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States smustgrave

    Can't give framework or frontend review unfortunately.

    But the failure in the MR seems valid.

    Also there are 24 unresolved threads able to close some of those out?

  • e0ipso Can Picafort

    > Also there are 24 unresolved threads able to close some of those out?

    I have been closing several of those. Some of the more involved, I left open for the original commenter to validate that my reply addresses their concern.

  • e0ipso Can Picafort

    @ctrlADel thanks for your feedback in #54.

    A few use cases I can think of:
    1. I have a design system from a client that contains components with twig/react/etc templates and ~75% of the definition SDC components need but the definitions are in a single json file, the missing 25% can be inferred from the 75%. How could a custom module create SDC components from that source?

    This seems like a very specific issue. I think I understand what you say, but a bit confused about it. I think this is doable with the current proposal. Since components are plugins, you can write a plugin deriver that generates plugins dynamically based off those JSON files.

    2. Some of the npm libraries I require via composer and install to the libraries directory have standard yaml SDC components in them. How do I get SDC to see them?

    SDC are Drupal plugins. It seems odd to distribute Drupal plugins using npm. I think those should be distributed using composer in drupal modules and themes. However, if you want to go that route you would need a Drupal module to integrate the npm package into Drupal. This is similar to how you need a Drupal module to use a PHP composer library you just imported.

    3. I add a third party setting to my SDC components in a multisite environment that lists which sites a component should be available on. How do I filter the list of available components based on this prop?

    The current component definition already has room for third party properties 🎉, so you are good to do this as well. However, I think that for filtering components, I would use the same techniques you use to have modules installed in a site and not another, instead of using the third party property.

    Pushing all the preprocessing in to twig with custom functions/filters is also less than ideal for a few reasons

    Yes. We agree on this. We are working on a proposal for preprocessing components (although there will be very few reasons for it, all preprocessing will happen in the "Drupal template"). This will be pushed for after beta. I am looking forward to see your ideas in that issue (I will create it soon, and link in the roadmap).

    I'm mainly thinking if you're trying to render the template in a js framework or Storybook using something like twig.js.

    There are no plans to support Twig.js. I believe it's counterproductive to Drupal, and it's proven to be unreliable once and again in the past. I wrote a bit about this topic in this post.

  • 🇬🇧United Kingdom catch

    I don't know much of the problems it caused, but QuickEdit was a complete paradigm change on editing content. SDC expands the current theme system capabilities, instead of forking them, so I don't anticipate such additional burden. SDC "only" relies on Twig, plugins, render arrays, and the libraries API, nothing exotic. In any case, let's be vigilant on this when we do the technical review.

    Another example would be RDF where we had to add all kinds of extra info to templates like #title_attributes and similar in order to inject RDF metadata all over the place. Even with RDF on its way out of core, we still have all that extra theme API layer left over which other code might or might not be using.

    Examples of things that are currently very hard to make progress on in the theme layer:
    📌 Provide a mechanism for deprecation of variables used in twig templates Fixed
    #1804614: [meta] Consolidate theme functions and properly use theme suggestions in core
    🐛 template_preprocess_node() does not add cacheability metadata Needs work

    What has happened over the past twenty years is that the number of theme hooks and preprocess variables proliferated across core, duplicating all kinds of information between multiple templates for the same basic markup, preprocess $variables, render arrays etc. We made a big effort early in the Drupal 8 cycle to de-duplicate some theme hooks so there could be less twig templates to convert, but that work is unfinished and to a large extent stalled.

    So a possible example where it might make things harder is if we deprecate either a whole template and that template is used in a component, would we have to add extra deprecation support for components, or would the template just be one more usage that gets a deprecation notice. And if that means deprecating an SDC too (because it turns out it duplicates another one), do we need to add support for that etc.

    I haven't done a proper review of the MR yet (although looks like @larowlan just has) so I don't know the answer to any of these, but those are the kinds of areas where things tend to get hairy.

  • 🇬🇧United Kingdom longwave UK

    Some points that came up while discussing this with core committers.

    1. I would like to see some concrete examples where this actually improves things for existing themes. The related issues 📌 Create new SDC component for Olivero (tabs) Postponed and Create new SDC component for Umami (Common Card) Fixed just seem to have a 1:1 mapping (3:3 in the Umami case) of template to component - the CSS and JS is rearranged (which I totally get as a good reason for doing this), but it also adds an extra layer of indirection in the original template and some metadata that appears to be effectively repeating hook_theme. I think it would help to have a good example, taken from core, that demonstrates why the extra indirection is actually useful and how it can reduce repetition somewhere (and if it can't, then I am not sure I see the benefit in adding this as-is).
    2. Regarding the metadata, in the Olivero tabs component the props are defined as
          properties:
            primary:
              type: array
              title: primary
            secondary:
              type: array
              title: secondary
      

      This feels like unnecessary boilerplate. Why is the title the same as the prop name? What is the benefit of declaring primary as an array? Why do we even need to declare the props up front?

    3. Similarly in the template, we now just map direct to a component:
      {{ include('olivero:tabs', {
        primary: primary,
        secondary: secondary
      }) }}
      

      Again this feels like a lot of boilerplate for not much gain.

    4. In $dayjob I'm already using a similar component mechanism; we do this purely in Twig with single components, for example a node teaser template:
      {% include '@basetheme/components/content/teaser-card.html.twig' with {
        text: content.field_short_summary,
        timestamp: timestamp is not empty ? timestamp : node.getCreatedTime(),
        wrapper_classes: 'bg-white',
      } %}
      

      As we're using Tailwind we don't actually need separate CSS files, but declaring JS and libraries separately is somewhat annoying and as I said earlier I do understand why we want to get away from this.

      However in another project we are using VueJS, which also uses single file components, and I really like that all the HTML, CSS and JS is kept together in a single file. Is this a possibility here? This is heavily inspired by Vue but I was hoping we could just use existing Twig syntax with front matter and new tags:

      ---
      props:
        - text
        - timestamp
        - wrapper_classes
      ---
      <section class="teaser-card">
        <div{{ wrapper_classes }}>
          {% if text is not empty %}
            <p class="text">{{ text }}</p>
          {% endif %}
          {% if timestamp is not empty %}
            <p class="timestamp">{{ timestamp }}</p>
          {% endif %}
        </div>
      </section>
      
      {% style %}
      .teaser-card { ... }
      .teaser-card p.text { ... }
      .teaser-card p.timestamp { ... }
      {% endstyle %}
      
      {% script %}
      alert('Scripts can go here too!');
      {% endscript %}
      
    5. Although the CSS belongs to the component, as far as I understand it there is no scoping of CSS going on here. That means you still have to be careful about reusing class names and writing your CSS so it doesn't affect other components. If somehow we could automatically scope CSS to the component only, that would be a really big win here for me.
  • 🇬🇧United Kingdom catch

    A more concrete question about re-usability:

    Off the top of my head, we have three or four 'card' implementations in core.

    One is the 'grid view' for admin/content/media-grid (which is also used inside media browser)


    the top of /admin/reports/status

    The front page of Umami


    If these are four or however many different card implementations for the different layouts, how would they be done so they can be re-used in different contexts? i.e. the media browser card shouldn't be media-specific, or possibly not even entity-specific? Same with the Umami ones.

  • 🇬🇧United Kingdom dreamleaf

    how would they be done so they can be re-used in different contexts? i.e. the media browser card shouldn't be media-specific, or possibly not even entity-specific?

    What would be really nice is a system that used pseudo-variables (or placeholders) within a SDC component. I don't even know if something like this is easily achievable with Twig but maybe the fields/variables are declared either within the json config or directly in the twig file (like we set attributes). Then when it's overridden, those declarations could easily be swapped out - and if the content was noticeably different from the original style - that is then amended within the component.

    The only other way it makes sense in my head would be to expose the component as a view mode, which would still require some form of pseudo variables that can be hot-swapped within the fields UI.
    Or along a similar line, also pull field_group into core, and have components exposed in there ..... obviously this is probably not going to happen and would be a contrib project, but it would be cool.

  • 🇺🇸United States mrweiner

    @longwave re: single file components, maybe check out https://www.drupal.org/project/sfc . I've implemented it on a project and absolutely love it (probably also because I love vuejs). It parses the styles and js from the sfc file and converts them into a library behind the scenes (along with other niceties).

    Although the CSS belongs to the component, as far as I understand it there is no scoping of CSS going on here. That means you still have to be careful about reusing class names and writing your CSS so it doesn't affect other components. If somehow we could automatically scope CSS to the component only, that would be a really big win here for me.

    True -- some sort of css scoping would be a big win. We use BEM to structure all of our sfc components to avoid these types of collisions.

    how would they be done so they can be re-used in different contexts? i.e. the media browser card shouldn't be media-specific, or possibly not even entity-specific?

    This is kind of the entire point of leveraging components. A "card" component and any variants would be provided somewhere other than media -- maybe a core_components module, or similar -- and then implemented wherever it's needed. If media wanted to re-implement or extend the base card component then it would be free to do so.

    ust seem to have a 1:1 mapping (3:3 in the Umami case) of template to component - the CSS and JS is rearranged (which I totally get as a good reason for doing this), but it also adds an extra layer of indirection in the original template and some metadata that appears to be effectively repeating hook_theme. I think it would help to have a good example, taken from core, that demonstrates why the extra indirection is actually useful and how it can reduce repetition somewhere (and if it can't, then I am not sure I see the benefit in adding this as-is).

    The only other way it makes sense in my head would be to expose the component as a view mode, which would still require some form of pseudo variables that can be hot-swapped within the fields UI.

    Another point for the approach that SFC takes, which is that you can designate a component as a template override, like so

    <?php
    $definition['overrides'] = [
      'node__article',
    ];
    

    I think a feature like this would be very nice to have (maybe a need-to-have) if a component system were to land in core. This also relates to @longwave's concern:

  • 🇬🇧United Kingdom catch

    This is kind of the entire point of leveraging components. A "card" component and any variants would be provided somewhere other than media -- maybe a core_components module, or similar -- and then implemented wherever it's needed. If media wanted to re-implement or extend the base card component then it would be free to do so.

    OK, but that's not what https://git.drupalcode.org/project/drupal/-/merge_requests/3657/diffs is doing with the Umami cards - which are just a title, image and 'read more' link.

  • 🇺🇸United States guschilds

    I would agree that 1:1 mappings with the variables getting passed as-is is not the most compelling example. In my experience it's best to keep any information about the data model out of component templates. The variables passed to the component should be simple and agnostic of entity types, bundles, field names, etc. I don't have enough experience with the core themes to know if the benefits will shine through, but an easy example is rendering teasers of many different entity types/bundles through the same component. All while keeping the model-specific stuff in Twig (the Drupal templates, being careful to maintain cache metadata) rather than PHP (preprocessing and/or clever theme hook suggestions).

  • 🇺🇸United States mrweiner

    OK, but that's not what https://git.drupalcode.org/project/drupal/-/merge_requests/3657/diffs is doing with the Umami cards - which are just a title, image and 'read more' link.

    I agree that the approach it takes is problematic in that the components themselves are tightly coupled to entity templates. Ideally any variables would be passed in (classes, title_prefix, etc) and content could potentially be variably positioned via slots (or {% blocks }%). But, to be fair, that issue has been postponed until everything is sussed out here.

    A general note -- when working with SFC, I found it useful to always use twig embed and include with the only keyword (i.e. {% include 'card' with { title: 'A title' } only %} to ensure that the component isn't polluted by variables that aren't explicitly passed in (i.e. props). Not sure how this concept fits into the vision for SDCs.

  • First commit to issue fork.
  • e0ipso Can Picafort

    These commits above implements feedback coming from the UI Patterns maintainers. When using the render array (it is likely that front-end developers won't use this as much):

    1. Rename the name of the render element. No more '#type' => 'sdc', it's '#type' => 'component' now.
    2. #slots now take only render elements, instead of strings with Twig code
    3. #context has been renamed to #props
    4. #slots_alter_callback and #props_alter_callback now take an array of trusted callbacks, and have been renamed to #propsAlter and #slotsAlter
  • 🇺🇸United States mherchel Gainesville, FL, US

    Replying to @catch in #60

    Off the top of my head, we have three or four 'card' implementations in core. One is the 'grid view' for admin/content/media-grid (which is also used inside media browser), the top of /admin/reports/status, the front page of Umami

    If these are four or however many different card implementations for the different layouts, how would they be done so they can be re-used in different contexts? i.e. the media browser card shouldn't be media-specific, or possibly not even entity-specific? Same with the Umami ones.

    I would argue that although these cards have the same visual layout, they’re very different components (except with the possible exception of the Umami cards). I can’t think of any situation where we would want to make the exact same change on all the cards across the various themes (where sharing the same component would help).

    I’d also like to say that although keeping things DRY is good, it can also lead to code that is very confusing to follow.

    SDC is not a good solution to combine the markup of these cards, because the markup of these cards should not be consolidated.

    I also want to highlight that the SDC feature is not expected to simplify the Drupal core codebase. But properly used, it will radically simplify the creation and maintainability of the vast majority of themes within Drupal sites.

    @guschilds alludes to the same thing in comment in comment #64, where he mentions, “I don't have enough experience with the core themes to know if the benefits will shine through”

  • 🇺🇸United States mherchel Gainesville, FL, US

    Replying to @longwave in #59.1

    I would like to see some concrete examples where this actually improves things for existing themes. The related issues #3347235: Create new SDC component for Olivero (tabs) and Create new SDC component for Umami (Common Card) Fixed just seem to have a 1:1 mapping (3:3 in the Umami case) of template to component - the CSS and JS is rearranged (which I totally get as a good reason for doing this), but it also adds an extra layer of indirection in the original template and some metadata that appears to be effectively repeating hook_theme. I think it would help to have a good example, taken from core, that demonstrates why the extra indirection is actually useful and how it can reduce repetition somewhere (and if it can't, then I am not sure I see the benefit in adding this as-is).

    Core themes (with the exception of Umami) are not what I would consider to be “real world” themes.

    When developing themes for a client website, there are frequently anywhere between 20-50 components of various types. These components are managed through a system such as Pattern Lab, Fractal, or Storybook. Components are also nested within other components – sometimes 2 or 3 deep.

    SDC is not meant to simplify Drupal core’s codebase. It’s meant to dramatically simplify the codebases of the themes that front-end developers are creating for their companies.

  • 🇫🇷France pdureau Paris

    Hello e0ipso, hello all,

    Here is my feedbacks about the current state of SDC.

    Before sharing them, I would like to thank you for this move. Adding UI components to Drupal core is a wonderful idea. We (sdc, ui_patterns , but also sfc and many other Drupal initiatives) may have different opinions about how to do things, but we agree it is something that must be done.

    Thanks also for the improvements done since December, and the changes done last 2 weeks.

    Those are my personal feedbacks, but they are shared by active members of the UI Patterns and UI Suite community.

    They are split in 3 layers, by order of importance:

    • Twig template structure and template inheritance bias
    • Definition YML file structure and overuse of JSON schema
    • Some "cosmetic" ones

    Twig template structure and template inheritance bias

    This may be a blocking issue for a possible rewrite of UI Patterns based on SDC. We agree a UI components solution in Drupal Core must be the basement shared by the modules staying in contrib. Unfortunately, the templates structures are not compatible.

    Default attribute object

    If our understanding is right, the default attribute object was renamed from attributes to componentAttributes because:

    • Preventing context sharing when the template is included, in order to avoid the injection of the node.html.twig/media.html.twig/user.html.twig... attribute object in the component template.
    • Some features of a planned sdc_devel module which will rely on this variable.
      • We disagree because developers has already many tools to prevent context sharing:

        • Using only keyword with include tag
        • Using the with_context parameter with include function
        • Using the embed tags

        Developers also have full control of the value they inject in the attribute object:

    {{ include('sdc_examples:my-button', {
      text: 'Click Me',
      iconType: 'external',
      attributes: whatever_you_want|default(create_attributes())
    }) }}
    

    So we don't see the need to change the variable name in the component template itselves, and maybe sdc_devel can use a mechanism compatible with the current convention.

    Block functions

    With SDC, only the props are injected as the template context. So, the slots are not avaialble as variables but as block tags and block() function.

    Block system has a purpose only when extending a template fom an othe template, and we don't believe this use case must disturb the component internal template structure.

      {% if block('body') %}
      <div class="button__body">
      {{ block('body') }}
      </div>
      {% endif %}
    

    Directly testing and printing the slot using a print node seems a cleaner and friendlier way of managing slots, independently of the usages.

    Conclusion and proposal

    Those incompatibilities come from the main use case studied to build SDC: template inheritance. So, SDC is pushing some changes into the usual Drupal template structure in order to make this use case more comfortable. Unfortunately, it makes the other uses cases (notably calling components from Drupal plugins, thanks to the Render API) less comfortable and weird.

    Definition YML file structure and overuse of JSON schema

    JSON schema is a good idea here, and it is a standard instead of a drupalism ("Getting off the island"), but it was not created to describe UI Components, and it seems overused here.

    Too deeply nested & required properties

    The schemas/*/properties levels seems unnecessary. They allow the declaration of the required properties, but this is a heavy structure to write for such a secondary feature.

    Indeed, required properties seem alien in a UI component model. A component must work with an empty context. To avoid an empty value, is better to use default values, at the JSON schema level and the Twig level (with |default() filter).

    Anyway, I guess there are more streamlined ways of declaring required properties if we really need to.

    JSON schema for slots

    Slots are free content so they can’t be strictly defined. We understood JSON schema on slots is only a convention in SDC, without any control and process related to them.

    So, if they are useless, they are misleading, and it would be nice to remove them to not expect from the developer the burden of writing them and reduce the confusion.

    JSON schema for props

    We believe using JSON schema for props is a good idea, and it is enough for simple data types:

    type: string for the strings
    type: [number, integer] for the numbers
    type: string, format: uri for the URL
    ...

    But, some will be more complicated:

    Color:

    {
      type: string
      pattern: "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";
    }
    

    Attributes:

    {
      "type": "object",
      "patternProperties": {
         "*": {
      	"anyOf": [
        	  {
             "type": ["number", "string"]
             },
        	  {
             "type": "array",
          	   "items": {
            	"type": ["number", "string"]
              }
        	  }
      	]
         }
      }
    }
    

    We need "shortcuts" for them, because it will be difficult for the developer to type such props without errors.

    Also, we need those shortcuts for modules like UI Patterns which will generate a site builder experience from those schemas, generating plugins attachable to config entities (blocks, layouts, field formatters, view rows...):

    We have tested a solution based on JSON schema $ref & $def mechanism but it didn't work.

    Examples

    It is not a good idea to put examples inside the props and slots. We made the same mistake in UI Patterns and we are now trying to fix it. People will want to build examples at a component level, not at a slot & props level.

    Conclusion and proposal

    As said before, JSON schema seems overused here, instead of simpler solutions.

    "Cosmetic" feebacks

    Not a big deal, but we believe it will make SDC a bit better.

    Metadata

    It seems Drupal plugins are using id instead of machineName: PluginInspectionInterface::getPluginId

    And label instead of name, because a lot of plugins are doing that.

    Libraries

    It is great there is a way of manually define libraries when the automatic discovery is not enough.

    library key would be nicer than libraryOverrides, and merging it with libraryDependencies would look cleaner and more usual for the people already familiar with the *.libraries.yml file structure.

    Cheers,

  • e0ipso Can Picafort

    w00t! I was looking forward to this post @pdureau, even if I already know what the content was from our conversations. Still, I continue to be amazed by your organization skills and attention to detail.

    TL;DR I think the blockers are solvable (one was already solved and pushed last night).

    I need to find the time to respond to the posts above in more detail. I have read you all, but I need some more time to reply.

  • 🇬🇧United Kingdom jonathanshaw Stroud, UK

    I'm in awe of #70 too :)

    #59 I would like to see some concrete examples where this actually improves things for existing themes. The related ... and Create new SDC component for Umami (Common Card) Fixed just seem to have a 1:1 mapping ... of template to component ... [which] adds an extra layer of indirection in the original template ... I think it would help to have a good example, taken from core, that demonstrates why the extra indirection is actually useful and how it can reduce repetition somewhere (and if it can't, then I am not sure I see the benefit in adding this as-is).

    My understanding is that in Create new SDC component for Umami (Common Card) Fixed when core/profiles/demo_umami/themes/umami/templates/content/node--card-common.html.twig does this ...

    {{ include('umami:card-common', {
      node: node,
      url: url,
      content: content,
    })}}

    ... it is acting as a presenter template, which is a widely shared pattern in Drupal-based component systems. Some kind of intermediation like this is always necessary if components are to be agnostic of the data model of the system that is feeding them.

    Agnostic components are necessary for code reuse between contexts in a theme, between themes, between projects, between organisations and even between CMS. The price we pay is that intermediation - data translation - is necessary.

    This intermediation can be done in php (e.g. in a preprocess hook) using ['#type => 'component'], or it can be done in a twig template as in the above example.

    It may be that core themes are too abstract and high-level to have the amount of need for code reuse that a large normal project has, and so there may be no good ways of demonstrating the value of components in a core theme that don't make it seem like as much complexity is being added as is being removed.

    #62 some sort of css scoping would be a big win

    I'm interested to hear @e0ipso's thoughts on this.

  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    We discussed this amongst committers (@longwave, @lauriii, @catch, @nod_, @gabor myself) and there was agreement the concept of "components" with a defined schema for props/slots is a good one to have in core 🎉

    So with broad support, we can now focus on the implementation of that concept. We have the following items we'd like to discuss/explore

    We'd like to hear from the team why single directory components are better than single file components. We'd like to explore the possibility of single file components as a possible end state. In that scenario the schema would be present as front matter, css in a

    tag, js in a tag. twig in a tag. The file path to the css/js would be the hash of the twig file and the component name (e.g. mytheme--button--hash.css). This might be as simple as adding #3050386: Allow loading CSS and JavaScript directly from templates to the path to stable roadmap. We'd like to explore if the new dynamic css/js aggregation could be leveraged to extract and write the css/js from the twig file. A twig filter would be needed to remove the style and script tags during twig render, and replace them with attach_library. There is prior art at https://www.drupal.org/project/sfc that could be referenced. All of this would bring us closer to the syntax of Vue's single file components, which may help those new to Drupal thening. To be clear we wouldn't require this for MVP but we'd like to see a roadmap of if/how we could get to that end-state, including BC/deprecations required. Additionally, as catch/longwave already commented above - we'd like to see any conversions that core did set good examples and we'd like to avoid proliferation of components in core where.they duplicate existing theme hooks and twig templates. Thanks again for all the work so far. Also, amazing feedback pdureau 😍
  • 🇷🇺Russia Chi

    tag, js in a tag. twig in a tag

    In general, a component may also need a definition in YAML format, images, fonts, documentation and probably some PHP code for preprocessing hooks. Also single file components require support from IDEs.

  • 🇺🇸United States mherchel Gainesville, FL, US

    So with broad support, we can now focus on the implementation of that concept. We have the following items we'd like to discuss/explore

    That's encouraging to hear! There are lots of reasons to prefer single directory components over single file components, I'll organize my thoughts and post sometime this weekend!

  • e0ipso Can Picafort

    there was agreement the concept of "components" with a defined schema for props/slots is a good one to have in core 🎉

    I wish I could reply with a celebratory GIF (soft G).

    We'd like to hear from the team why single directory components are better than single file components. We'd like to explore the possibility of single file components as a possible end state.

    We did talk about SFC in our initial meetings. But I will let @mherchel elaborate that from a front-end developer perspective.

  • e0ipso Can Picafort

    There is a lot of feedback in #70. I will start addressing it. I might not have time to do it all in one sitting.

    Twig template structure and template inheritance bias

    Default attribute object

    componentAttributes (formerly sdcAttributes) are generated for the component itself. It is completely independent from the attributes that the presenter template receives. While the attributes will contain HTML classes and attributes related to the current node, the componentAttributes will contain HTML classes and attributes related to the component (.sdc--my-card .sdc--component, etc).

    As you can see the existence of componentAttributes is not related to context leaking, it responds to:

    • Having predictable class names and HTML attributes by default.
    • Having class names that are free of name collisions. This is important because CSS is global by nature.

    This will be helpful for CSS scoping because all components get a top level HTML class without name collisions. Leading to less styling unexpected interactions when combining components. With predictable class names there can be 3rd party JS tools that interact with components in a reliable way.

    Of course any developer can skip componentAttributes (as they are optional). The side effect is that they won't get the additional attributes.

    Block functions

    As of recently when you use the render element, all slots are also added to the template context under the keys: slots.[slot-name]. I think this makes the problem go away entirely for UI Suite, since it will be always using the render element.

    With these two things in mind (componentAttributes is optional and slots are available in template context):

  • 🇺🇸United States mherchel Gainesville, FL, US

    Reply to @larowlan's comment in #73

    We'd like to hear from the team why single directory components are better than single file components. We'd like to explore the possibility of single file components as a possible end state.

    Why single directory components instead of single file components?

    I’ve worked with Vue before ,and although I see the value in single file components (esp with Tailwind), I also believe that they’re a poor fit for Drupal core.

    • Components are frequently much more than CSS/JS/markup. Components frequently include images, and could also have other binary files such as custom fonts, WASM, etc. I’ve seen things like this solved by putting all assets into their own directory before, but then we’re back at SDC.
    • Support for multiple JavaScript files. Within core, Olivero’s navigation system contains approximately 277 lines of JS logically split among three files. It would be negatively impact the developer experience to combine that into one file
    • Support for external JS files (such as web components). I’m a big fan of standalone web component files (see https://github.com/davatron5000/awesome-standalones) that can fit perfectly into the SDC workflow. The same critique can apply to React, et al.
    • Support for CSS preprocessing / Postprocessing. I’m not sure how Sass or PostCSS can work with this. Note that if we do get this working (I’m 100% sure it’s possible), we’d likely be on the hook for the maintenance of this toolchain.
    • Support for JS processing such as Babel / TypeScript, etc. Same note as above

    Once again, Single File Components are valuable, but support for this belongs in contrib. I believe that eventually 80% of new Drupal sites will eventually be using Single Directory Components, but I would not believe that even 20% would do Single File Components.

  • e0ipso Can Picafort

    Reply to @larowlan's comment in #73 from a more back-end perspective. There will be some overlap with @mherchel's comment above.

    We'd like to hear from the team why single directory components are better than single file components. We'd like to explore the possibility of single file components as a possible end state.

    Twig is not JS, it doesn't have any of the vibrant ecosystem. We don't have any of the tools Vue has to turn those custom-format SFC into standard files, in compile time. In other ways, to split a SFC into a SDC.

    In Twig we have custom loaders, which we can use as a run-time parser of styles + JS + eventual PHP. This means front-end devs are stuck with what they write in twig SFCs, since it is" way harder" to support an SFC that contains Twig + SASS + Typescript + PHP than the SDC equivalent. By way harder I mean that there are no SASS & Typescript compilers written in PHP, and injecting the JS versions in the Twig loader lifecycle will not be possible. All these build steps are not theoretical or site-only, this happens as well for our post-CSS and es6 JS in Drupal core.

    Now let's imagine we solve these problems and we have a compile-time process that splits SFC into SDC (maybe with a node visitor, regular expressions, and temporary files), so you can put Babel/Webpack/... on top. This could be our solution to support SFC in Drupal core using SDC as its foundation.

    However, in our discussions we considered that even then SFCs are not a good solution. By having SFC in core:

    • We have an intermediate format that IDEs don't understand, and that will not likely try to support (imagine working without autocompletes).
    • We have a format that our browsers won't point to in debuggers (no source maps from what the browser is running to the typescript embedded in the SFC).
    • We have a format that is text only (which excludes binary files like images, fonts,...).
    • We have a format that code quality tools will not support (which leads us to turn them off).
    • We have a format that is unique to Drupal that surprises both new-comers and old-timeys.
    • We have a format that we have to document and maintain the documentation for.
    • We have a format that gets more confusing as a compo­nent grows (imagine scrolling back & forth us. having 3 editor tabs open).
    • We have a format that is potentially controversial (while I enjoy secs where the tooling & stack is ready, not everyone does).

    I do see the point of SFC, it aims to improve DX. that is one of our primary goals. However, the price we pay is huge, and the benefit is not. In any case we can have SFC as a producer of SD Cs in contrib, and see if the hurdles we anticipated are not a problem, but I believe we should let SDC mature in core first while we figure out all those issues.

  • e0ipso Can Picafort

    Continuing with the feedback from #70.

    Definition YML file structure and overuse of JSON schema

    JSON schema is a good idea here, and it is a standard instead of a drupalism ("Getting off the island"), but it was not created to describe UI Components, and it seems overused here.

    JSON Schema was created to describe arbitrary JSON structures. I think it works really well to describe the typical UI component metadata. Maybe some of its features are less relevant, but they are not mandatory.

    Too deeply nested & required properties

    The schemas/*/properties levels seems unnecessary.

    The problem I see with your proposal is that it does not conform to JSON Schema. I think the best approach here is to describe the props object, not each one of the keys in there. This will give us more consistency and simplify the process of validating the input data. Otherwise we'll need to construct the schema ourselves on the fly.

    Indeed, required properties seem alien in a UI component model.

    I do think that a UI component can have required properties. Default values will not always be relevant. I would rather get a nice error in my development environment saying the my CTA has no text, than a generic default text that has nothing to do with the content.

    JSON schema for slots

    I agree with you, JSON Schema for slots is not as relevant. As we mentioned in our talks they should go away.

    Or a more minimal example:

    Note two things:

    • It is desirable to keep the ability to provide extensive optional metadata to slots (and props). This will allow us in the future to auto-generate forms for components based on the schema with 0 additional effort. This is key for future projects that aim to provide user site builder/editorial user input for components.
    • The new proposal loses the ability to mark slots as required. Since slots are more content focused, I can see the argument that they will not be key structural parts of a component.

    While I agree that JSON Schema for slots is not as relevant, I also acknowledge that we want to be able to gather all that data for other purposes (forms component libraries, etc). The new streamlined format is not much more streamlined, and loses us the ability to declare required slots (unless we start a new & very similar format to JSON Schema).

    I am happy to compromise in here for slots with this proposal, but it is not my preference.

    JSON schema for props

    The fact that JSON Schema lets you describe complex data shapes, does not mean that it is a good idea for your components to have complex data shapes. In fact, I have not seen many components with that complicated input. Instead of a polymorphic prop that can be string or array, you will likely have two separate props.

  • e0ipso Can Picafort

    Final round of addressing feedback from #70.

    "Cosmetic" feedbacks

    I don't have much of an opinion about this. Let's see what others think about the proposed changes. The one that I like the most is to merge libraryDependencies into libraryOverrides.

  • e0ipso Can Picafort

    Regarding the questions in #59 from @longwave:

    1.

    but it also adds an extra layer of indirection in the original template and some metadata that appears to be effectively repeating hook_theme.

    I think the level of indirection here is also desired. It's like a PHP refactor where you take some of the logic out on a method because it's used in some other class. But then you have to call the new method, it's not enough to define it.

    In the case of components extracting them is beneficial for two reasons:

    • It promotes code re-use.
    • It decouples the UI from the presentation model.

    2.

    This feels like unnecessary boilerplate. Why is the title the same as the prop name?

    This is JSON Schema. Having the title same as the prop name is an implementation choice from the contributor. One is the machine name and the other is the human readable name.

    On a side note I am with you, I think both types should be string, not array.

    3.

    It is likely that in a less pre-processed environment you will find something like:

    {{ include('olivero:tabs', {
      primary: content.field_foo,
      secondary: preprocessed_value|default('I am a default')|trim
    }) }}
    

    Again, this is the equivalent of calling $this->newMethod($variable['something'], $something_else) after extracting some code into a new method.

    5.

    as far as I understand it there is no scoping of CSS going on here.

    CSS scoping without output transformation like emotion does is not something I can envision. Sadly, there are not PHP based tools (and much less compatible with Twig/Drupal) we can use as an alternative to that.

    The best effort we can do is to encourage component authors to use componentAttributes in their templates so they get name classes that are designed to have very unlikely chances of name collisions. I touched on this a bit in #77.

  • 🇬🇧United Kingdom jonathanshaw Stroud, UK

    @e0ipso #77 While the attributes will contain HTML classes and attributes related to the current node, the componentAttributes will contain HTML classes and attributes related to the component (.sdc--my-card .sdc--component, etc).

    It seems to me that in 90% of cases the attributes and componentAttributes both along on the outermost html element of the component.

    To serve that use case what you're expecting is something like this:
    (assuming [#262396] is addressed)

    node.html.twig:

    {{ include('components:my_article', {
      title: node.title,
      body: node.body,
      attributes: attributes,
    }) }}

    components/my_article/my_article.twig:

    {% set attributes = attributes.merge(componentAttributes) %}
    <article {{ attributes }}>
    <h2>{{ title }}>/h2>
    ...

    What I'm wondering is about doing the merging automatically, so a component always has an attributes prop that contains a merge of both the new attributes you've discussed for the component, and any attributes passed in. Then the component doesn't have to do the merging, simplifying significantly the 90% use case.

    Attributes becomes a kind of special prop that every component has: you can pass things into it, but what you get in the template contains more than what you passed in.

    If the themer really wants all or some of the drupal attributes separately from the component attributes, they can just assign them to a custom prop called something other than "attributes":

    node.html.twig:

    {{ include('components:my_article', {
      title: node.title,
      body: node.body,
      my_node_attributes: attributes,
    }) }}
  • 🇪🇸Spain idiaz.roncero Madrid

    I agree with @jonathanshaw here, this is something that also arose during the POC of SDC proof of concept: Olivero messages .

    Having to separately handle both the old-fashioned attributes and the newer, component-scoped componentAttributes might be confusing at first and break some things, especially with third-party JS libraries that rely on markup.

    Think for example a very common pattern where some functionality is added on top of existing HTML by using data-attrs, like Boostrap tooltips:

    <button data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top">
      Tooltip on top
    </button>
    

    The tooltip here is an "addition" to the button component, not a part of it. It seems OK that a third-party contrib module might want to alter the attributes of any renderable element just to add that little markup, but SDC would break this.

    You can extend this to, i.e., helper (utility) classes, tailwind-like (.mb-0, .pt-5), that might be added from outside the scope of the component to provide for easy, drop-in overrides. This is a pattern I do not like but it's been gaining a lot of traction and we can't ignore it. Alas, there are already several Drupal contrib modules that allow to alter attributes via UI, etc...

    I agree that the solution to this problem might be that these kind of "alterations" don't belong into the component and they should be placed maybe on a wrapper around it when needed. But even if it this pattern is not OK, it is already happening on the Drupal community.

    Due to this, when enabling SDC and starting to work with it many themers could see a sudden loss of functionalities, failing third-party JS libraries, modules that seem to fail to populate classes or attributes, etc.

    A solution could be, as @jonathanshaw Add Single Directory Components as a new experimental module Fixed said, to automatically provide a merge of both attributes and componentAttributes and let the developer decide when to manually skip it.

    If not, I think this should be handled carefully (documentation, FAQs and other informational resources) because it might feel as a a big breaking change / pain point when it comes to SDC integration with the overall Drupal module ecosystem. Since drupal front-enders and module developers are used to having a shared attributes object passed along and extended by modules and themes, this might feel like a breaking change for many of them.. I think we should be careful with that kind of frustration and how this might affect adoption.

  • 🇮🇪Ireland markconroy

    I'm glad that @mherchel and @e0ipso have commented in #77 and #78, because it saves me typing out the same thing.

    I fully endorse their positions on SDC vs SFC.

    One other issue that I think SFC will create is making it harder to have variations of components. For example, in Umami we have a view mode for card and one for card alt and one for card common. We then have a css file for card.css and card-alt.css and card-common.css. The latter two css files are very small. If we had SFC then I'm not sure how we'd be adding these small variation CSS files, I'm sure we'd figure it out but I wouldn't like the solution being we use single file components except for variations where we use single file components for the main components and single directory components for the variations.

  • e0ipso Can Picafort

    For the record, I was talking to someone the other day, and they suggested the exact same as #83. Unless there is opposing feedback, I will be implementing this merging solution soon.

  • 🇬🇧United Kingdom jonathanshaw Stroud, UK

    If componentAttributes goes away, then componentMetadata should probably become component.

    Unless we already have a naming convention we should emulate for some other variable that gives a template information about itself, not sure if there is such a variable.

  • 🇺🇸United States mrweiner

    Re: #79, having worked extensively with SFC, I can offer some insights

    We have an intermediate format that IDEs don't understand, and that will not likely try to support (imagine working without autocompletes).

    This is true, with caveats. It may be possible to configure IDEs such that they can understand these files, depending on how they are structured. See discussion in https://www.drupal.org/project/sfc/issues/3202242 💬 Document IDE support Active , with approaches for both vscode and phpstorm. My experience with phpstorm is that it works, but there are some pains. You can get it all working with PHP autocompletion, but there are issues with code autoformatting that jetbrains doesn't want to work on. It's likely that if we did implement SFCs in core, we might need to maintain IDE plugins or provide documentation on how to get things working if the front matter suggestions can be made to work out of the box.

    We have a format that our browsers won't point to in debuggers (no source maps from what the browser is running to the typescript embedded in the SFC).

    Yes and no. SFC module generates JS files behind the scenes which are easily inspectible. The SFC itself isn't referenced, but the JS files are generated per component anyway so it's trivial to make the associations during debugging.
    We have a format that is text only (which excludes binary files like images, fonts,...).
    True. I don't think it's the end of the world to create a directory when things need to be associated with an SFC, but I can see why one wouldn't consider it ideal.
    We have a format that code quality tools will not support (which leads us to turn them off).
    Yes, this can be a headache.

    We have a format that is unique to Drupal that surprises both new-comers and old-timeys.

    Unique in implementation, but not in principle. As was mentioned, vue leverages SFCs. Just because something isn't as familiar doesn't mean it's a wrong approach per se.

    We have a format that we have to document and maintain the documentation for.

    True, but we will also need to document and maintain everything for SDCs as well.
    We have a format that gets more confusing as a compo­nent grows (imagine scrolling back & forth vs. having 3 editor tabs open).
    The people arguing for SFCs will disagree with this. I 100% prefer working with SFCs ,both in drupal and in vue, even for longer components. If I want to have two tabs open for markup and styles, I can just open the file in two tabs, no big deal. Like the SFC maintainer said in the parent issue "Less files === more good, which is SFC's unofficial slogan, probably."

    Re: #85

    One other issue that I think SFC will create is making it harder to have variations of components. For example, in Umami we have a view mode for card and one for card alt and one for card common. We then have a css file for card.css and card-alt.css and card-common.css. The latter two css files are very small. If we had SFC then I'm not sure how we'd be adding these small variation CSS files, I'm sure we'd figure it out but I wouldn't like the solution being we use single file components except for variations where we use single file components for the main components and single directory components for the variations.

    Not exactly sure what the issue is, here. Why couldn't a variation just include its own css? Those very small stylesheets would be inlined like any others.

  • e0ipso Can Picafort

    It seems from #88 that some of the concerns have only partial solutions, others don't have solutions. There is an argument that this is common in Vue, yet it is also notable that it is not common in React, Angular, or 95% of UI frameworks using components (made up number, I didn't do a statistic for this).

    I agree with @mrweiner's in his assessment that 3 tabs vs 1 long file comes down to personal preference.

    Not exactly sure what the issue is, here. Why couldn't a variation just include its own css? Those very small stylesheets would be inlined like any others.

    Variants are different flavors of a component that can have a different template. We de-scoped them from the MVP for core inclusion. If we decide to support them we will likely have N templates for 1 component definition, 1 set of binary assets, etc. Since SFC couple everything together you cannot have a single component definition with multiple variant templates. @markconroy, correct me if this isn't what you were referring to in #85.

    I still can't see how we'll allow developers to use SASS or TypeScript without complicated setups. I strongly believe that Drupal core's solution for components should allow using these technologies, and others to come.

  • 🇨🇦Canada xmacinfo Canada

    I did not find the answer for this:

    In Single Directory Components, where would we store SVG files in /components and how would we call those SVG files? Can we support both SVG files (file.svg) and inline SVG (

    )? For example, I see some components using SVG to add icons, or add dynamic SVG illustrations, like a chart.
  • 🇪🇸Spain idiaz.roncero Madrid

    This might be off-topic, but re: sass or typescript compiling, I've always thought that Drupal Core's front-end scripts and package.json build/watch/ scripts (which were used for *.es6.js files and are used for *.pcss files, but only work for /core folder) should be more readily available for module/theme developers .

    Some old issues like this one pointed on that direction.

    That could 1) provide the tooling out of the box for whoever wants to use it instead of rolling out their own solutions, dependencies, etc... and 2) ensure some standards are enforced, by using common .prettier .eslint and .stylelint files from the core, the same way there are PHPCS Drupal and DrupalPractice standards for the back-end.

  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    @idiaz.roncero - I think that warrants opening a separate issue (looks like the other one was closed).

    Now we have starterkit, that would be a logical place for it to live.

  • 🇺🇸United States mherchel Gainesville, FL, US

    In Single Directory Components, where would we store SVG files in /components and how would we call those SVG files? Can we support both SVG files (file.svg) and inline SVG (

    )?
    Pretty sure you could do something like <img src="images/file.svg"> or {{ include('images/file.svg') }}
  • @e0ipso opened merge request.
  • e0ipso Can Picafort

    I opened the MR to the MR above to run all tests in CI. All went as expected (including base branch test failures). Merging and closing.

    Thanks @larowlan for the tests refactor! 🤩 I learned quite a lot from this.

  • e0ipso Can Picafort

    @xmacinfo There is an example of that in the SDC Examples repo. I hope that clarifies things.

  • First commit to issue fork.
  • 🇪🇸Spain ckrina Barcelona

    I see all my concerns with SFC have been pointed in #78, #79 and #85.
    Focusing on the front-end DX experience, not being able to let people choose to preprocess/postprocess CSS or JS processing is a big deal. And on a code quality perspective not being able to use code quality tools too.

    In any case we can have SFC as a producer of SDCs in contrib

    From Mateu comment in #79 SFD efforts could be moved into a contrib. That means SDC wouldn't be blocking those willing to use SFC, and wouldn't enforce this solution to the rest. For me, this should be enough to move forward with the current SDC strategy.

  • e0ipso Can Picafort

    It feels like I have written a novel already in this issue, but I acknowledge that something may have escaped me. There have been multiple threads open at the same time in various moments. The excitement and engagement here is an incredible motivator for me to keep trying, but I might have missed something. Now that I feel I am caught up with feedback, I will turn again to addressing the technical feedback.

  • 🇫🇷France pdureau Paris

    Hi Mateu, all,

    Twig template structure and template inheritance bias

    Answering #77.

    Default attribute object

    The componentAttributes will contain HTML classes and attributes related to the component (.sdc--my-card .sdc--component, etc).

    So, there will be specific SDC HTML classes like the classes added by views (.views-view, .view-content...) or fields (.field-name, .field-type, .field-label). It is something teams implementing a design system with Drupal will not need and will try to avoid as much as possible (as we are already painfully removing the other Drupal wrapper classes).

    It is at least possible to also automatically inject an empty attribute object as the attribute prop if it is missing from the context? I think a lot of us will only use this one.

    Note: I see in comments #83 and #84 that a merge of componentAttributes into attributes is asked. It also may be a solution, because we will be able to filter out the .sdc--* classes from this attributes object.

    Block functions

    Let me reword the table headers:

    It is obvious the example with {% block body %}{% endblock %} doesn't allow to skip the print of button_body if body is empty, so the third example doesn't provide the same feature as the two first.

    Slot manipulation is not only about if tags. Let's picture a slider, the slide slot is a list of slides of unknown length, and we are looping on them to add a wrapper:

    <div class="slider">
    {% for slide in slides %}
      <div class="slider__slide">
      {{ slide }}
      </div>
    {% endfor %}
    </div>
    

    Same with a grid row component (mixing loop and conditions):

    {% if content %}
    <div class="row">
    {% for col in content %}
      <div class="col">
      {{ col }}
      </div>
    {% endfor %}
    </div>
    {% endif %}
    

    So, the proposal of moving away from the block tag is not "the old UI Patterns way everyone else should not do", it is a proposal to improve SDC and the only way to comply with real life needs. In the other hand, promoting the block tag way as the "good" way will confuse people.

    Having a slot map with slots as children is a good step in the right direction, thanks Mateu. It may even be good enough. But it would be sad to stop there and not inject the slots directly in the context. We are nearly there.

    Definition YML file structure and overuse of JSON schema

    Answering #80

    Too deeply nested & required properties

    I would rather get a nice error in my development environment saying the my CTA has no text, than a generic default text that has nothing to do with the content.

    I have trouble picturing the need because in this example, the CTA should have been a slot and not a prop. Do you have an example with a proper prop?

    17 years of Drupal, 11 years of design systems methodology, 6 years of UI Patterns... I have looked in my many previous experiences and I didn't see any need for a required prop in an UI Component, which can't be managed by a default value.

    Required data is useful for business modelling, but UI components don't do business modelling.

    JSON schema for slots

    I agree with you, JSON Schema for slots is not as relevant. As we mentioned in our talks they should go away.

    Great!

    JSON schema for props

    The fact that JSON Schema lets you describe complex data shapes, does not mean that it is a good idea for your components to have complex data shapes. In fact, I have not seen many components with that complicated input. Instead of a polymorphic prop that can be string or array, you will likely have two separate props.

    Beyond the theory, let's have a deeper looks on the 2 examples provided in #70:

    Single file component

    I 100% support the answers of Mike (#78) and Mateu (#79).

  • e0ipso Can Picafort

    Having a slot map with slots as children is a good step in the right direction, thanks Mateu. It may even be good enough. But it would be sad to stop there and not inject the slots directly in the context. We are nearly there.

    I feel this is very close! My hesitation in mixing the props and slots at the root level in the context, when using the render array, is name collisions. If we go down this path, we also need to ensure that the static validation step of the component metadata throws a meaningful error if there is a collision between props and slots. I think this can work well!

    17 years of Drupal, 11 years of design systems methodology, 6 years of UI Patterns

    Woot! It's so great to have your experience validate the ideas in here. I'll say it once and again!

    Required data is useful for business modelling, but UI components don't do business modelling.

    You are likely correct. However, in the past I have used prop-types to model props for React components (UI components after all). They do offer the ability to require props. My preference is to support required types, and let component authors decide weather or not to use this feature. In other words, I think we should propose a solution that allows for required props, in case we decide in the future that we want them.

    I think the color prop with format validation is perfect. I honestly don't see a problem with it. The attributes example should be simplified with 'type' => 'Drupal\Core\Template\Attribute'.

    But let's assume this was not enough, and we wanted to have an alias system. The good news is that JSON Schema already comes with it! And our parser library justinrainbow/json-schema knows how to resolve the aliases. I don't want to get into specifics, but we can have local or remote JSON files that contain schemas for complex properties, and then reference them using $ref. Drupal core already has examples of this, we put it in for JSON:API.

  • 🇫🇷France pdureau Paris

    The good news is that JSON Schema already comes with it! And our parser library justinrainbow/json-schema knows how to resolve the aliases. I don't want to get into specifics, but we can have local or remote JSON files that contain schemas for complex properties, and then reference them using $ref. Drupal core already has examples of this, we put it in for JSON:API.

    That's what I have tried. However, I didn't success to merge the properties from the type and the ones from the prop.

    I moved the type definition to a $defs:

      "$defs":
         icon:
            type: string
            enum:
             - power
             - like
            - external
    

    Now I set a prop using this type:

    dismiss_icon:
       title: Dismiss icon
       description: Visible only if the alert is dismissable.
       "$ref": "#/$defs/icon"

    Unfortunately, they didn't merge.

    I used JSON schema every day in my professional life but I am far from being an expert, and I don't know the deepest stuff.
    Do you know a way? (looking at jsonapi/schema.json didn't help)

  • e0ipso Can Picafort

    This latest commit addresses one of the outstanding issues componentAttributes. These have been controversial, and the separation of attributes from the Drupal templates, vs. componentAttributes from the component templates has been a confusing concept even for seasoned developers.

    Resolution

    • The patch above drops componentAttributes entirely.
    • It also drops the auto-generated classes sdc--my-component, and alike.

    If the component receives a prop called "attributes" and it's of type Drupal\Render\Template\Attribute (the good old attributes we have everywhere), then SDC will add the data-component-id="my_theme:my-component attribute to it.

    If there are no attributes passed to the component, a SDC will inject them containing the usual data-component-id="my_theme:my-component.

    This addressed concerns from @larowlan (on how the default classes didn't feel great), @pdureau, @mherchel, @jonathanshaw.

  • 🇬🇧United Kingdom catch

    The arguments for SDC against SFC are good, I think it more or less boils down to:

    - 'I want to be able to put CSS in a .css file, and js file in a .js file and then load them normally with normal things, not a chimera'
    - 'while vue does it, there's an infrastructure of tools around it which Drupal doesn't have'
    - it would be easy to provide SFC as an additional option/subset of SDC in contrib.

    all of which are good reasons.

    One further question I have though is why putting custom CSS and JavaScript in the YAML vs using #3050386: Allow loading CSS and JavaScript directly from templates ?

    And another question I have (not related to SDC vs. SFC) is if the Olivero tabs aren't a good example of a component, why bother converting them at all?

  • e0ipso Can Picafort

    One further question I have though is why putting custom CSS and JavaScript in the YAML vs using #3050386: Allow loading CSS and JavaScript directly from templates ?

    The vast majority of cases, likely 95% of the time, you will not have to put CSS and JavaScript in YAML or anywhere. Just by naming your files my-component.css and/or my-component.js, they will be added to the page.

    The remaining 5% will be split between:

    • Adding an additional file, in setups without a build step.
    • Tweaking the attributes for the <script> or <link> tags.
    • Including a 3rd party dependency from a CDN

    Of those, only #1 is covered by #3050386: Allow loading CSS and JavaScript directly from templates . In fact, I could see how that is the recommendation for #1. However, we still need to support libraryOverrides for #2, and #3.

    So all in all, adding JS and CSS directly in the templates will be useful in SDC in a very small fraction of the uses, but still useful in those occasions.

  • 🇺🇸United States mherchel Gainesville, FL, US

    And another question I have (not related to SDC vs. SFC) is if the Olivero tabs aren't a good example of a component, why bother converting them at all?

    Although tabs isn't a great example as far as passing in props / slots, there is still a benefit of encapsulating the code. With tabs being a component, we can see that all the relevant code in one place.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Updating issue summary

  • e0ipso Can Picafort

    There are some changes coming to the metadata file syntax as a result of feedback in this issue:

    This is an annotated example of a component metadata file including the proposed changes above. This covers all options, in reality your components will be much shorter.

    # Optional This is so your IDE knows about the syntax in this file for fixes and
    # autocomplete.
    $schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
    
    # Required. This is the name of the component. The component plugin ID will be
    # <module-or-theme>:<machineName>.
    machineName: tabs
    
    # Optional. The human-readable name for the component.
    name: Tabs
    
    # Optional. Status can be: "experimental", "stable", "deprecated", "obsolete".
    status: experimental
    
    # Schema for the props. We support www.json-schema.org. Learn more about the
    # syntax there. This is optional for themes, unless the
    # 'enforce_prop_schemas: true' is set in the theme's info file.
    props:
      # Props are always an object with keys. Each key is a variable in your
      # component template.
      type: object
      # If your component has required properties, you list them here.
      required:
        - primary
      properties:
        # The key is the name of the variable in the template.
        primary:
          # Optionally, you can add a human-readable name to your props.
          title: Primary
          # This variable is an array of strings: ['foo', 'bar', 'baz'].
          # This information is required for every prop.
          type: array
          items:
            type: string
    
    # Slots always hold arbitrary markup. We know that beforehand, so no need for
    # a schema for slots.
    slots:
      # The key is the name of the slot. In your template you will use
      # {% block body %} ...
      body:
        # An optional human-readable name.
        title: Body
        # Mark it required if necessary. Optional.
        required: true
        # An optional description.
        description: This is the body
      # Only the key is required when declaring slots. This is how you declare a
      # slot with minimal typing.
      minimal: {}
    
    # Optional. This is how you take control of the keys in your library
    # declaration. The overrides specified here will be merged (shallow merge) with
    # the auto-generated library. The result of the merge will become the library
    # for the component.
    libraryOverrides:
      # Once you add a key in the overrides, you take control of it. What you type
      # here is what will end up in the library component.
      dependencies:
        - core/drupal
        - core/once
      # Here we are taking control of the JS assets. So we need to specify
      # everything, even the parts that were auto-generated. This is useful when
      # adding additional files or tweaking the <script> tag's attributes.
      js:
        my-component.js: { attributes: { defer: true } }
        my-other-file.js: {}
    
  • 🇬🇧United Kingdom longwave UK

    Some thoughts on #110:

    1. Why machineName over id? Plugins and other Drupal YAML generally use id. This was also raised in #70
    2. Should the machine name be optional, and the directory name used as the machine name by default?
    3. Why are required props listed in a single key at the top level, but required slots have a separate key on each slot?
    4. Theme YAML uses libraries-override instead of libraryOverrides; should we be more consistent?
  • 🇺🇸United States bnjmnm Ann Arbor, MI
    1. One further question I have though is why putting custom CSS and JavaScript in the YAML vs using #3050386: Allow loading CSS and JavaScript directly from templates?

      I can weigh in as the person who wrote the patch for that one. The craziest code in my solution is fully due to not having the asset names/path until the template is parsed. Having them available via matching filename or yml eliminates the most complex part of that solution that is doing some pretty wild stuff.

    2. There seem to be plenty of good reasons to not go SFC already, but I'd like to add that this would require additional tooling (or we'd at least need to actively acknowledge we lose the benefits of our CSS/JS tooling with SFC). Getting the linters, etc configured to handle things properly seems like a less than ideal ROI at this stage. If there's continued interest in SFC it seems like it could be an expansion of SDC, as opposed to a discrete alternative.
  • e0ipso Can Picafort
    • Why machineName over id? Plugins and other Drupal YAML generally use id. This was also raised in #70
    • Should the machine name be optional, and the file name or directory name used as the machine name by default?

    I like the idea of using the directory name as the machineName and remove it altogether from the component definition! One less thing to make match.

    The component itself has a name, but each prop/slot has a title. Should these be the same?

    This is JSON Schema. SDC only needs the type information.

    However, adding more descriptive metadata will allow for contrib to have a richer experience. A library that builds Drupal forms from JSON Schema definitions can leverage the description field for the #description property in Form API, it can see the enum property in the schema and generate '#type' => 'options', etc. Other integrations will use other schema properties.

    Why are required props listed in an array at the top level, but then required slots have a separate key on each slot?

    Slots have a known schema. We will allow some metadata for integrations to use, but not the full JSON Schema. We thought that we could simplify the slot definitions. WRT required slots, that was my mistake. Slots will not be required. I have deleted that from the annotated example above.

    Theme YAML uses libraries-override instead of libraryOverrides; should we be more consistent?

    I like the idea. I wonder if libraries in plural makes sense in this context.

  • e0ipso Can Picafort

    These past few commits above address the feedback in recent posts that were summarized in #110. This will change component definitions, hopefully, for the last time.

    They also implement the changed agreed on #103 about:

    My hesitation in mixing the props and slots at the root level in the context, when using the render array, is name collisions. If we go down this path, we also need to ensure that the static validation step of the component metadata throws a meaningful error if there is a collision between props and slots. I think this can work well!

  • e0ipso Can Picafort

    I have verified, that the schema compatibility checker (used when replacing components) and the input data validation are not correctly expanding the schemas based on $ref. This was correctly highlighted by #104.

    I have a prototype in my local that addresses this. Expect changes to support this.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    I have refrained myself for doing another +1 please do this but: +1 please do this.

    In the (unofficial-yet) dashboard initiative we are soonish needing to reconvert part of e.g. the status report page to blocks that could be reused in a dashboard. See an example here for the last cron run "component" (pun intended): Provide a block for running cron from a dashboard Needs work

    The status page is one of those that could benefit a lot from having sdc in core.

    As we are gonna need to work on that refactoring, I hope that when we get to that we can already use SDC and avoid refactoring again in a couple of months.

  • e0ipso Can Picafort

    As I dig deeper into schema references (per #104) I find more and more complexity. I propose moving schema references out of the MVP for beta. We can add them later before becoming stable.

    I created [PP-1] Allow schema references in Single Directory Component prop schemas Postponed and added it to the roadmap ( 🌱 Single Directory Components module roadmap: the path to beta and stable Active ).

  • Status changed to Needs review about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US
  • 🇫🇷France pdureau Paris

    Hi Mateu, hi all,

    Wow! So much changes those last days. Thanks a lot for this hard work.

    So, I did some new tests today, from this git HEAD:

    $ git show 
    commit d35d23f9509b7f9802c95941064760139e012087 
    Author: Mateu Aguiló Bosch (e0ipso) <mateu@mateuaguilo.com>
    Date:   Sun Apr 2 22:04:14 2023 +0200
    Merge branch '10.1.x' into 3340712-add-single-directory

    Here are the results.

    Twig template structure and template inheritance bias

    • Default attribute object: tested Tuesday 4th April with mixed results:
      • ✅ : an "attributes" Attribute variable is injected by default in the template and can be manipulated from the template
      • ⚠️ : however, if attributes prop is initiated/altered from the render element, it is not injected in the template
    • "normal" variables instead of block functions :✅ tested OK Tuesday 4th April: my slots are available as variables in the template

    Definition YML file structure and overuse of JSON schema

    • Too deeply nested & required properties: ✅ the removal of "schema" level is considered as a good enough simplification. And it still the best way to express required props.
    • JSON schema for slots : ✅ tested OK Tuesday 4th April. I have declared slots without using JSON schema and i didn't get any warning or dysfunction.
    • JSON schema for props: 🕑 In progress. Moved to an other issue: [PP-1] Allow schema references in Single Directory Component prop schemas Postponed

    "Cosmetic" feedbacks

    • Metadata : I didn't check, but not a big deal, so let's put this away
    • Libraries: ✅ not tested but saw in comment #110 libraryDependencies was merged into libraryOverrides as dependencies

    All this looks good.

  • e0ipso Can Picafort

    I have manually confirmed that our safe guards drupal_escape and Twig Sandbox are still in effect. This was expected, since we are not replacing anything, but hooking into Twig. Nevertheless, this was due diligence.

    Debugger stopped in the escapeFilter while rendering SDC:

    Debugger stopped in the TwigSandboxPolicy while rendering SDC:

  • e0ipso Can Picafort

    These two commits above address a potential rename of the module after experimental phase, but before stable. A module rename implies a class namespace change, so we want to avoid anyone depending on the current class names.

    1. We want to avoid use of service names that point to future non-existing classes
    2. We want to mark every class/interface/trait/enum/... as @internal
  • 🇺🇸United States dww

    I've been excitedly following progress in here. Amazing work everyone (especially @e0ipso)!

    I was somewhat shocked to find 📌 Introduce ExtensionTypeInterface with public constants for extension types Needs work as a blocker, so I've mostly been working in there instead of here. Based on our findings so far, that's more complicated than it first seems, we need to sort out the scopes for a series of issues we're going to need to split it into, etc. Via Slack, @larowlan, @mherchel, @e0ipso and myself agreed that #3350946 should not be a blocker to this. We can add some @todo comments pointing to 📌 [PP-2] Port SDC to use ExtensionTypeInterface Postponed where appropriate, but otherwise leave all the SDC code to directly use 'module' or whatever as needed for now. We can work on #3350946 in parallel. Once both that and this have landed, we can do #3352546. But this can/should proceed into core without worrying about it.

    Thanks again!
    -Derek

  • 🇺🇸United States dww

    For now, looks like a single @todo for the docblock in core/modules/sdc/src/ExtensionType.php should be enough. Crossing that off from remaining tasks. Almost there! 😉

  • e0ipso Can Picafort

    Woo! one less fence to circumvent. Thanks @dww!

  • Status changed to RTBC about 1 year ago
  • 🇫🇷France pdureau Paris

    I am happy and proud to be allowed to switch the status to RTBC.

    Please note:

    • The community review I did (with the help of the UI Patterns people) is based on "functional" real life usages as both:
      • a front developer implementing design systems components
      • and a back developer using those components through the render API
    • So I didn't check stuff like code quality of test coverage, but more skilled reviewers reviewed the MR.
    • The last blocking point according to my review was moved to a sub issue: [PP-1] Allow schema references in Single Directory Component prop schemas Postponed
    • There are no preprocess hooks for components templates. It is a bold and great move I fully support because it makes components rendering more sandboxed and predictable, but early adopters need to be aware of this limitation (of course, the preprocess hooks for "Drupal templates" / "presenter templates" are still available)

    This long-awaited addition will be very valuable to Drupal Core, I hope it will be integrated as soon as Drupal 10.1.

    However, this low-level API is only a first step: there will be both an ecosystem to build on Contrib space, and more features and refinements to add in future Core releases.

  • 🇺🇸United States bnjmnm Ann Arbor, MI

    Myself and fellow FEFM's @nod_ @ckrina and @lauriii met with @e0ipso etc. to finalize what would be needed to get the FEFM signoff, which turned out to be getting the Stable roadmap completed. 🌱 Single Directory Components module roadmap: the path to beta and stable Active is looking good so I'm going to remove the "needs FEFM review" tag.

  • Status changed to Needs work about 1 year ago
  • 🇬🇧United Kingdom longwave UK

    Added a number of review comments.

  • e0ipso Can Picafort

    I addressed the first round of feedback. I think tests should be green at this checkpoint. I will continue with the rest.

  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    Second (and final) round of feedback from @longwave addressed. Setting back to NR.

  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Setting back to Needs Work 😬. A SDC test is failing

    Sdc.Drupal\Tests\sdc\Unit\UtilitiesTest
    ✗	
    Unknown
    fail: [run-tests.sh check] Line 0 of :
    FATAL Drupal\Tests\sdc\Unit\UtilitiesTest: test runner returned a non-zero error code (2).
  • Status changed to Needs review about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    🙌

  • 🇺🇸United States cosmicdreams Minneapolis/St. Paul

    I gotta say, as someone who thought it may never be possible to be working fully with both Drupal and Web Components, this is giving me a lot of hope.

    With web components, I have seen previous work that can analyze a web component and generate a json definition file based on that anatomy it discovers. The format it produces like likely not Json Schema but it could be a nice intermediate step (just needing a bit of tweaking) to get it in the right format. Generating schema is not the 80% use case scenario as a dev team would likely build their components from scratch while building a Drupal site. Not all dev teams are ea.com and salesforce, teams with existing large design suites with a hundreds of components to integrate with a Drupal site. But it's nice to know they could without a giant effort.

    I think what I'm seeing from this proposal is that, if I wanted to, I could drop in a web component or two and it might even be as easy as dropping in a twig template. Am I dreaming?

  • Status changed to RTBC about 1 year ago
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    This was RTBC before on #127. All feedback since then has been addressed. All tests are passing.
    All tasks in the road to experimental roadmap in 🌱 Single Directory Components module roadmap: the path to beta and stable Active have been fixed.
    There is consensus (and even some hype) on Single directory components in core Active to add this to core as experimental.

    This is still marked as Needs framework manager review, I'm not sure if it has been reviewed in that capacity but I've seen plenty of comments from a Framework Manager.

    Let's get this in before the alpha-1 !

  • Status changed to Needs work about 1 year ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I've done a pretty thorough code review. Still thinking about the overall architecture.

  • e0ipso Can Picafort

    I pushed a commit that addresses all feedback from @alexpott. I expect code checks to fail. I will work on those later, unless someone else beats me to it.

  • e0ipso Can Picafort

    Very high level architecture.

  • Status changed to Needs review about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I discussed what this looks like when the module moves from experimental to part of the core API with @e0ipso and @catch. The current module name is sdc which is a bit cryptic but it probably does not matter because this functionality should not be modular - it should be part of the core API. Previously when we've added a module that will eventually end up in core we've used class aliases - see https://www.drupal.org/about/core/policies/core-change-policies/experime...

    This leads to the question of what is the API here. In discussion with @e0ipso we agreed that the API is:

    • The render element name and class - the render element type is component
    • The exceptions
    • The plugin manager service - named plugin.manager.sdc
    • The functions added to twig - sdc_additional_context and sdc_validate_props
    • The folder structure for a component

    Therefore we should:

    • Document in the readme what we consider the provided API to be
    • mark all classes apart from \Drupal\sdc\Element\ComponentElement final
    • Alias \Drupal\sdc\Element\ComponentElement to \Drupal\Core\Render\Element\ComponentElement
    • Alias all the exceptions to \Drupal\Core\Theme\Component\Exception (is this the correct namespace)???
    • (done)

    Starting off this strict in the module will make it easy to remove final from a class and provide a core alias is a use-case occurs during the alpha or beta stage of development.

  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Excited for all of this feedback! Setting back to NW to implement the changes in #141

  • 🇩🇪Germany geek-merlin Freiburg, Germany

    #141: Great clarification.

    Which raises a question for me:

    > The plugin manager service - named plugin.manager.sdc
    > The functions added to twig - sdc_additional_context and sdc_validate_props

    Shouldn't we name it sth like "plugin.manager.components" then?

    Otherwise in 5 years we'll have to tell our children "Yah, that's a historical artifact and i only dimly remember that it was about some implementation detail" ;-).

    #139: Nice diagram!

  • 🇩🇪Germany geek-merlin Freiburg, Germany

    #141: And another question:

    > [APIs are] The functions added to twig - sdc_additional_context and sdc_validate_props

    If i grok the source right, these are functions that are added by ComponentNodeVisitor and only internal.
    If that's the case they should be marked as internal (i don't think there's a preceding case of such) and not API.

  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    Otherwise in 5 years we'll have to tell our children "Yah, that's a historical artifact and i only dimly remember that it was about some implementation detail" ;-).

    I love to picture a family drupaling together :-D

    I think this is not critical since we can create service name aliases. We can alias to the correct name (after we decide one). I don't know what is the process of marking a service name for deprecation, but we might want to do that. In any case this will happen before the module is stable, so no BC will be broken in any case.

  • e0ipso Can Picafort

    If i grok the source right, these are functions that are added by ComponentNodeVisitor and only internal.
    If that's the case they should be marked as internal and not API (i don't think there's a preceding case of internal twig function though).

    I think I caused this confusion. While talking to @alexpott about the API i mentioned the Twig functions as being the main API. What I meant was that our main API is in how the Twig functions/tags include, embed, and extends are used. In particular the template name format [module/theme]:[component machine name]. Breaking this naming convention will be a BC break.

    As pointed by geek-merlin, sdc_additional_context and sdc_validate_props can stay internal.

    Hopefully this will make more sense after the README is updated.

  • e0ipso Can Picafort

    Alias all the exceptions to \Drupal\Core\Theme\Component\Exception (is this the correct namespace)???

    I think this namespace makes sense. I will use it, unless there is opposition.

  • e0ipso Can Picafort

    I added the documentatio about the module's API in https://www.drupal.org/docs/develop/theming-drupal/using-single-director...

    Document in the readme what we consider the provided API to be

    @alexpott, I added the documentation in the guide since I didn't see core modules with README files. Let me know if you still want to capture this in the codebase, or the drupal.org documentation page is fine.

  • e0ipso Can Picafort

    I completed all the tasks from #141.

    • Document in the readme what we consider the provided API to be (done)
    • mark all classes apart from \Drupal\sdc\Element\ComponentElement final (done)
    • Alias \Drupal\sdc\Element\ComponentElement to \Drupal\Core\Render\Element\ComponentElement (done)
    • Alias all the exceptions to \Drupal\Core\Theme\Component\Exception (is this the correct namespace)??? (done)
    • Make all the services private apart from the plugin manager (done)
  • Status changed to Needs work about 1 year ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    So I think we need to do 3 things before my framework manager review is complete:

    1. I think we need to document the public API commitments discussed above in the README
    2. I had another think about where the classes from this are likely to end up (i.e. the plugin manager class) to be sure we've got the correct class aliases for the excepptions. The options appear to be \Drupal\Core\Theme\Component, Drupal\Core\Template\Component or Drupal\Core\Render\Component - I'm really not sure what's best. Although I think my original choice in #141 might be the worst :)
    3. We need to fix the remaining 4 threads on the MR

    Nearly there!

  • 🇺🇸United States cosmicdreams Minneapolis/St. Paul

    Regarding the triad of choice from #150:

    Render might be the most Drupal-y choice. Most other things that render that aren't form elements are render elements. But if chosen, are we comfortable with developers assuming that components share logic / methods / are similar to other Render elements?

    Do we attempt to document any differences between render elements and components?

    (I'm not sure what differences, if any, there are)

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update about 1 year ago
    Custom Commands Failed
  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    @alexpott, I added the documentation in the guide since I didn't see core modules with README files. Let me know if you still want to capture this in the codebase, or the drupal.org documentation page is fine.

    I think we need to document the public API commitments discussed above in the README

    I added a README.txt in the module per #150. I am hoping this is what you meant @alexpott.

    I moved the exceptions to Drupal\Core\Render\Component. I share the same preference as @cosmicdreams. I think that Theme doesn't quite fit because modules also provide components. I think that Template is close but non-ideal because it may be confusing since the template is only a part of a component.

    I finally addressed the MR open threads that I missed last time (one day we'll have comments and inline feedback in the same place).

    I added new test coverage:

    1. Test that the enclosing folder can have any name, not necessarily the component machine name.
    2. Test that the plugin manager re-throws the exception when there are incompatible schemas
    3. Centralize schema definitions in metadata.schema.json.
    4. More thorough validation of the component metadata file in edge cases. This uncovered a problem with PHP array to object uncertainty with empty arrays. I have verified that other packages (like composer) also deal with this by using "type": ["object", "array"].
  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Setting back to NW to fix the PHPCS

  • First commit to issue fork.
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update about 1 year ago
    29,275 pass, 2 fail
  • e0ipso Can Picafort

    The test error seems legit. It's for one of the new tests I added in the last push. I will look into it.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Obviously we need to fix the tests but I'm satisfied that my final round of feedback in #150 has been addressed and so we can remove the "Needs framework manager review" tag.

    This passes the frame manager manager review for me because:

    • SDC will be useful to several contrib projects and providing this in core means less duplication
    • SDC can help Drupal shops produce common components to share across their builds (and hopefully share with the community)
    • We have a documented limited API surface area enforce by the use of final where appropriate
    • We have sufficient test coverage of the code
    • We have a plan in place for how to move the code to core and remove the SDC module
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    4:54
    3:17
    Running
  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    Ah! I see the PHPCS fixes in #154 removed the necessary bar.component.yml because of the linter. I added it back with the contents of null, which will test the same as if it were empty. Crossing fingers for green tests.

  • e0ipso Can Picafort

    I just saw #156!

    Wooot! One step closer!

    /giphy excited and eager

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Saving issue credit. Crediting issue reviews and all the thoughtful discussion on this issue. Also added credit to @Gábor Hojtsy and @lauriii for behind the scenes committer work.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Committed d1faffc and pushed to 10.1.x. Thanks!

    Thanks for all the great work and fantastic discussion on this issue.

  • Status changed to Fixed about 1 year ago
    • alexpott committed d1faffc7 on 10.1.x
      Issue #3340712 by e0ipso, alexpott, larowlan, dww, _pratik_, catch,...
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    As this is an experimental module it won't be in the 10.1.0 release so I'm not sure that this needs a change record or be tagged with release highlights tag yet. That said, I'm not sure where we'd announce this so people know to try it out in dev.

  • 🇺🇸United States cosmicdreams Minneapolis/St. Paul

    Woooooo!!!!! For me, this is the most awesome thing to happen in Drupal this decade

  • 🇺🇸United States mherchel Gainesville, FL, US

    As this is an experimental module it won't be in the 10.1.0 release so I'm not sure that this needs a change record or be tagged with release highlights tag yet. That said, I'm not sure where we'd announce this so people know to try it out in dev.

    My understanding is that ALPHA releases don't go into the release, but BETA releases do (which this is).

    From https://www.drupal.org/about/core/policies/core-change-policies/experime...

    If an alpha experimental module does not reach beta-level stability before the alpha phase of a given minor release (e.g. 8.5.0-alpha1), it will be left in the new development branch (e.g. 8.6.x), but removed from the release branch (e.g. 8.5.x) before the alpha release is tagged. As of Drupal 8.5.x, we will no longer ship alpha-level experimental modules in stable releases of Drupal 8.

  • 🇪🇸Spain idiaz.roncero Madrid

    🎉🎉🎉🎉🎉🎉 !!!

  • 🇺🇸United States cmlara

    Considering the drupal/sdc namespace is reserved by https://www.drupal.org/project/sdc shouldn't this core module do one of the following:

    • Use a new namespace to avoid conflict with the existing reserved namespace.
    • Have the DST or Core Committers (depends who you want to have authority for avoiding the collision attack) take ownership of https://www.drupal.org/project/sdc project and keep it in sync with core until at least D11. Due to the existing release constraints allowing ^9.5 and ^10 are possibly install targets for the contrib modules, similar to how we rolled ckeditor4 from core into contrib. After D11 is released the namespace just needs to be held in custody.
    • Add a replace section to the core composer.json (though this conflicts with 🐛 Remove the "replace" section from core/composer.json Fixed )

    See #3081434: Module project name conflicts with D7 contextual links where these collisions have happened in the past when core adopted an in-use namespace.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    @cmlara / re #172

    • when this code goes stable the sdc module will not exist - the code here will be part of core/lib/Drupal
    • The sdc module in contrib was a laboratory for this code and has a core maintainer already as a committer
    • The sdc module in contrib has never had a stable release
  • 🇪🇸Spain unstatu

    Veeeery happy to see this hapenning. Thanks to all!

  • e0ipso Can Picafort

    I created 📌 Mark SDC as beta so it can be included in 10.1 Fixed to discuss marking SDC as beta stability before 10.1.0-alpha1 is tagged ⏳. This will mean that SDC will be available as an experimental module in 10.1.

  • 🇺🇸United States cosmicdreams Minneapolis/St. Paul

    Just to close the loop here: Yes! It's possible to create a SDC component that wraps a web component: https://www.drupal.org/project/pokemon_card

    There are a few things to improve like:

    • Figure out how to compile my js into the component's .js file
    • Figure out how high in the hierarchy the library dependencies need to be defined.

    This is a promising start.

  • 🇺🇸United States Dave Reid Nebraska 🇺🇸

    I would still like to keep iterating on the sdc module in Drupal 9 and Drupal 10.0 if we could. I firmly believe that we should fix https://www.drupal.org/project/project_composer/issues/3309838 🐛 Incorrect version of CKEditor being parsed from info.yml files Active instead of getting rid of the contrib module.

  • 🇩🇪Germany geek-merlin Freiburg, Germany

    Wooooooot! Awesome!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024