Problem/Motivation

Drupal 10 will not support IE 11. That means that it will now be possible to use web components within Drupal without polyfills.

Some opportunities and questions presented by that:

  • Where does it make sense to use web components within Drupal core? One example is that Shadow DOM can help us with #2195695: Admin UIs on the front-end are difficult to theme. Another example might be to use web components as a better implementation of Drupal render system placeholders, per #2602726: As an alternate to BigPipe, add a PlaceholderStrategyInterface implementation that renders placeholders as web components. Where else?
  • What do we want to add to core to better support front-end developers and/or site builders in adding web components to their sites? For starters, how do we want site builders adding a web component's JS code to their site? Libraries API and Component are two current ways, and there are likely others. Do we want core to provide an implementation of one of those or something else?
  • Besides adding the JS library of the web component, how else do we want to expose that component to the site builder to use? For example, do we want to automatically provide blocks for some web components (that's what the Component module does)? Do we want to automatically make a CKEditor toolbar button for adding that web component available to be added to a text format's CKE configuration? What else?

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

effulgentsia created an issue. See original summary.

effulgentsia’s picture

Issue summary: View changes
andypost’s picture

There's also https://www.drupal.org/project/components module which provides discovery

cosmicdreams’s picture

When considering components it might be good to agree on an organizing design philosophy or way of categorizing components. Have a common terminology or way of thinking about these components. Beyond the thinking of present day philosophy of component-based design there is an enumeration of how Web Components can be interacted with. I'll try to break that idea down below:

Presentation Components

These components typically have no business logic. They handle simple to complex template rendering. They exist to satisfy the user story of the a development group that provides components for content creators, in a way that provides sensible defaults and "guard rails" that prevent the content creators from getting themselves into trouble.

The development group can center their thinking about web components as a way to provide a kind of Presentation API, that provides extensibility and variability in how a component is used, while enumerating and limiting the kinds of interactions that a content creator has available to them. That way the components can more reliably deliver good results, while reducing the confusion content creators may have by limiting all the things that can be done with them.

Data driven components

These are components that handle integrations with data services. They include things like being able to iterate/stamp out multiple template items from a data feed. There are tons of opportunities of these kinds of components with a standard D10 site. We've put a lot of work into providing data feeds for every kind of entity. It's difficult to think of what's not possible.

This may be controversial ground though. We've made excellent progress with integrating with React. This may not be fertile ground for our first integrations. Something simpler like the aforementioned contextual links might be better. Something that still behaves as if it were a presentational component but accepts data as attributes or inner body markup.

Data driven components examples:

  • Contextual Links
  • Embed View
  • Embed Entity
  • Embed Video
  • Autocomplete link
  • Geocode an address

App-like components

These components glue together multiple data driven components to behave like an embedded application. This is where the complexity is. Given time, I suspect we'll see a lot of these kind of components grow in Drupal. Although, I think that pursuing these kinds of development might be more that we have capacity for at the moment. Things like:

  • Layout Builder
  • Block Placement page
  • Content Admin page
rlnorthcutt’s picture

The "component" module provides a pretty handy way to accomplish this. Components are defined with a *.component.yml file, and then Drupal autodiscovers and makes them available. These components can be loaded as blocks or as libraries, and used as needed. This approach was also taken independently by the "js_component" module, and we are looking to consolidate these approaches.

The good news is that this pattern has been in use for quite some time and has the advantage that it is very easy for a JS developer to utilize without needing to learn PHP or complex Drupalisms. It also leverages Drupal core concepts like library management, dependency tracking, block configuration, etc... so getting it into core (or something like it) should be fairly easy.

rlnorthcutt’s picture

Another worthy example is the Project Browser initiative. I wanted to use the component module to make it easy to surface this in the UI, but since it is slated for core inclusion, we can't use contrib dependencies.

100% agree that we need a solution like this in core.

andypost’s picture

nod_’s picture

Status: Active » Postponed

Postponing to simplify triage of the ideas queue on the component topic.

It would be helpful to highlight the needs addressed by this idea in the issue summary and add it to #3240805: [meta] Organize components-related ideas as well, to help consolidate all the different related issues.

cosmicdreams’s picture

Hey gang, if #3340712: Add Single Directory Components as a new experimental module becomes an experimental module for Drupal 10.1, would it be appropriate to revisit this question? I haven't spent a lot of time reading through / understanding the feature, but my read of the issue thread is making me hopeful that we might have support for ANY kind of component in core, including Web Components.

cosmicdreams’s picture

cosmicdreams’s picture

Last year, I built a fun but complex web component that would be a good test of single directory components / storybook integration and the whole stack of concerns.

pokemon-card

The challenge ahead

  • Can we parameterize inputs like type of Pokemon?
  • Can we support external libraries like svelte / lit without loading them once per component
  • Does SDC support work for various ways a component can be implemented? Svelte / Vue / lit / vanilla (just off the top of my head)
  • And how does implementing the component work for frontend devs
catch’s picture

Project: Drupal core ideas » Drupal core
Version: » 11.x-dev
Component: Idea » markup

Moving to core. I think #9 is still accurate.

catch’s picture

Issue tags: +Moved from Ideas queue
dalemoore’s picture

I'm personally using web components with Lit 3 and combining them with SDCs. It's been very effective!

I'm using Import Maps and this shim:

<script async src="https://cdn.jsdelivr.net/npm/es-module-shims@1/dist/es-module-shims.min.js"></script>

So that my Lit components don't have to change the path to finding Lit at the top of the individual .js files.

At the top of my html.html.twig I've included these references to the Lit libraries:

<script type="importmap">
      {
        "imports": {
	        "lit": "/libraries/lit/index.js",
          "@lit/reactive-element": "/libraries/@lit/reactive-element/reactive-element.js",
          "lit-element": "/libraries/lit-element/index.js",
          "lit-element/": "/libraries/lit-element/",
          "lit-html": "/libraries/lit-html/lit-html.js",
          "lit-html/": "/libraries/lit-html/",
          "lit/directives/class-map.js": "/libraries/lit/directives/class-map.js",
          "lit/directives/choose.js": "/libraries/lit/directives/choose.js",
          "lit/directives/style-map.js": "/libraries/lit/directives/style-map.js",
          "lit/static-html.js": "/libraries/lit/static-html.js",
          "lit/directives/if-defined.js": "/libraries/lit/directives/if-defined.js"
	      }
	    }
    </script>

In each SDC's component.yml, I add this at the bottom:

libraryOverrides:
  js:
    component-name.js: { attributes: { type: module }}

There's probably better ways to do this; if anyone has suggestions. My site is still in development. But the SDC + Web Component method I'm using works well. Using the import maps allows me to not have to deal with the build step stuff.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.