GithubHelp home page GithubHelp logo

Comments (6)

mattlucock avatar mattlucock commented on May 29, 2024

I've also seen in a similar way the need for collections of DOM elements to be built based on their shared DOM scope (main complexity beyond el.querySelectorAll(...) being the elements living in different DOM trees, but the same DOM scope), which if it were a shared issue could likely benefit from a shared protocol, as well.

I'd be interested in any particular examples of this you can share. I'm struggling to convince myself that this is actually a generic problem; indeed, I'm not sure this problem is actually relevant to the slottables proposal. In the context proposal, the protocol needs to determine what element is providing the scope, and there are (unresolved) nuanced aspects such as establishing the scope after the request has been made and dynamically changing which element is providing the scope. But to me these issues feel specific to the context protocol, and details of the 'scope' don't seem to be important to the slottables. My interpretation of the slottables proposal is that the 'scope' is inherently just the parent component, so no scope resolution actually takes place.

Events versus DOM walking/well-known method names is definitely a question I'm interested in, even though I'm unsure it's relevant outside of contexts. The benefit of context requests being events is that it lets a consumer communicate with a provider without knowledge of the provider and without the responsibility of determining who the provider is. Using a bubbling event to traverse ancestors, including the ability for an ancestor to stop the bubbling at at a certain point, as a means of implementing context is a really clever idea, and I don't think I would have come up with it myself. I think the reason I wouldn't have come up with it, though, is because I'm unsure it's semantically correct. An event in the DOM is supposed to notify anyone who may be listening of an occurrence or change in state, but this isn't really what context requests are. Furthermore, I don't think an emitter should care or even have knowledge of whether anyone is listening, but context requests specifically expect a response. So overall I think I'm torn on the issue.

from community-protocols.

Westbrook avatar Westbrook commented on May 29, 2024

This is a simplified draft of these three use cases that I think it might be possible to support with a shared approach to communication across a DOM tree, but it's still quite theoretical, so thanks for your participation in the discussion! As I gather information here, I'm very much trying not to prescribe a solution, which is why I went with "DOM Scope Request Resolution" so that the conversation could flush out the best solution (or solutions) for the use cases available.

  1. DOM-based context: one or more descendant requests to have a shared DOM ancestor resolve a single JS value or many things ask for the same value.
  2. Slottable Request: a single descendant requests to have one or more ancestors resolve to address one or more DOM elements to a prescribed <slot> or one things asks for many values.
  3. DOM element collection: one or more descendants request to have a shared DOM ancestor resolve to include them in a central collection of elements or many things ask to have a value they hold (possibly simply themselves) added to the same collection.

Relationships across the DOM tree are the important factor in each that leads me to position the question of there being a shared overarching protocol that could support clarifying them all. In each, the difference from "historic" element development, where the element is a mini-application, is the idea that there can be an external owner of a state-like entity. An external owner should not be considered "required", so a holistic protocol should clarify how the individual requester could "self-resolve" in all of the cases.


Number three might be flexible to broader use cases, but I specifically find the need for it in establishing list content across complex DOM trees. In a way, it's a process by which the client can create flattened trees. For example, a <select> element resolves its relationship with <option> elements and <optgroup> elements by direct parent-child DOM structuring.

<select>
   <option>0</option>
   <option>1</option>
   <!-- ... -->
   <option>n</option>
</select>

<!-- OR -->

<select>
   <optgroup label="Group 0">
     <option>0</option>
     <option>1</option>
     <!-- ... -->
     <option>n</option>
  </optgroup>
  <!-- ... -->
   <optgroup label="Group N">
     <option>0</option>
     <option>1</option>
     <!-- ... -->
     <option>n</option>
  </optgroup>
</select>

Requiring this relationship means that one could leverage el.children, a single MutationObserver, or similar to handle this use case within a custom element:

<x-select>
   <x-option>0</x-option>
   <x-option>1</x-option>
   <!-- ... -->
   <x-option>n</x-option>
</x-select>

Ignore for a moment the reality that <selectlist> is coming, and it has slightly more relaxed relationships here, but what if the actual DOM in that comes together looks more like:

<composed-select>
#shadow-root
| <x-select>
| #shadow-root
| | <x-option>Default Option 0</x-option>
| | <x-option>Default Option 1</x-option>
| | <!-- ... -->
| | <x-option>Default Option N</x-option>
| | <slot></slot>
|   <x-option>Applied Option 0</x-option>
|   <x-option>Applied Option 1</x-option>
|   <slot name="root"></slot>
|   <!-- ... -->
|   <x-option>Applied Option N</x-option>
|   <x-optgroup>
|   #shadow-root
|   | <x-option>Default Option 0</x-option>
|   | <x-option>Default Option 1</x-option>
|   | <!-- ... -->
|   | <x-option>Default Option N</x-option>
|   | <slot></slot>
|      <x-option>Applied Option 0</x-option>
|     <x-option>Applied Option 1</x-option>
|     <!-- ... -->
|     <x-option>Applied Option N</x-option>
|     <slot name="group"></slot>
|   </x-optgroup>
| </x-select>
  <x-option slot="root">Applied Root Option</x-option>
  <x-option slot="group">Applied Group Option</x-option>
</composed-select>

Here, the collection that is being created is a coalescence of DOM elements from four different DOM trees. All of the options that should be collected share one or more ancestor elements any of which could be the scope at which the request was resolved.

Starting from the same, the options in the above example all have cost, at some point of scale, that cost will be such that you won't want to pay it unless the options are interactive (e.g. the <x-select> is open). This is where a slottable request would relate to this approach in that was <x-select> to make that request when it is opening, then it would need to be resolved across three (or more) DOM trees to completely fulfill the expected interface.

from community-protocols.

mattlucock avatar mattlucock commented on May 29, 2024
  1. Slottable Request: a single descendant requests to have one or more ancestors resolve to address one or more DOM elements to a prescribed <slot> or one things asks for many values.

I don't think this is a correct interpretation of the proposal. The proposed slottable-request event does not bubble, so there is no 'scope' in the way that you describe. I think the idea is just that the user who instantiated the component knows that it will dispatch these events and will listen for them, but this doesn't involve a relationship across the DOM tree; slottable requests are not actually made to an ancestor. Also, if an arbitrary ancestor was aware of and could respond to slottable requests, that would theoretically be a violation of encapsulation.


I agree that the select/option use case, or more generally the 'input group' use case, is interesting, but I've seen this problem before in React, and contexts is how people solve it; here's one source I could easily find.

You theorize that contexts are a specialization of the idea of a shared DOM scope, but part of me feels like contexts may actually be the generalization of the idea.

from community-protocols.

Westbrook avatar Westbrook commented on May 29, 2024

What's great about a well-written spec is that it is flexible beyond its original intentions. Much like the <slot> spec likely didn't take into account stacked slots (e.g. <slot name="custom"><slot></slot></slot>), the slottable request protocol doesn't have to explicitly outline the relationship I have for it to make it possible. Here's an example, if you want to follow along: https://studio.webcomponents.dev/edit/1g4cC4DRhZyQhetNqKBf/stories/index.stories.js?p=stories

However, that protocol is still very much in the ideation phase, and the discussion herein specifically calls out that it, the Context Protocol, and others may be better served by a more generic protocol. They may even be better served by entirely different mechanisms for achieving their stated goals, whether in terms of performance, ergonomics, or general understandability. In that way, I'm trying not to constrain what could be possible here by what may or may not be possible there.


If the request for items in a list can be resolved by a single context at the list host, this may not be a genuinely new use case. I'll spend some time with your link and see how it resonates. Immediately, the context owner and the collection owner seem to be the same (at least as leveraged in the article you shared), which is not true in my example. I may be misinterpreting, as I'm not much of a React developer, so I'll get back to you on that later.

In my example, it's important to understand, and maybe it's easier to do so in the live example rather than the example rendered DOM, that the owners of the individual items are different but the individual items themselves coalesce into a single collection. We're specifically seeing the benefit of this in organism-level components that exemplify a shared user experience but surface specifics of the consuming application. With this capability, the design system can say you need the "List *" and "Group *" items, but the application can say you need the "Composed *" items and the state can say you need the "External *" items.

from community-protocols.

mattlucock avatar mattlucock commented on May 29, 2024

What's great about a well-written spec is that it is flexible beyond its original intentions. Much like the <slot> spec likely didn't take into account stacked slots (e.g. <slot name="custom"><slot></slot></slot>),

I disagree with this example. I don't think the 'stacked slots' behavior you show is especially interesting or surprising; I think it's the normal behavior of slots working exactly as intended (not to say you shouldn't have written about it; it's cool).

the slottable request protocol doesn't have to explicitly outline the relationship I have for it to make it possible. Here's an example, if you want to follow along: https://studio.webcomponents.dev/edit/1g4cC4DRhZyQhetNqKBf/stories/index.stories.js?p=stories

It's not obvious to me what you intend for this example to illustrate. The point that I was trying to make is that not only does the proposal literally not involve some kind of DOM scope, but that it would theoretically be a bad thing if it did, since such an arbitrary scope would theoretically violate the encapsulation of the owning context. In your example, a component requests slotted content from its owner, which it provides, but part of the content is content that the owner requests from its owner. Again, I don't think this is particularly interesting or surprising; I think it's just the normal behavior of the protocol as proposed working exactly as intended.

However, that protocol is still very much in the ideation phase, and the discussion herein specifically calls out that it, the Context Protocol, and others may be better served by a more generic protocol.

I can't spot the discussion you're referring to in the proposal or the PR. Can you link me to it?

Re: the rest, I think I am fundamentally not understanding what it is you desire. You seem to be saying that a parent scope should be able to coalesce a collection of relevant descendant elements from various descendant DOM trees, but in general it's not apparent to me why we'd want to do that or what it would achieve. The example that I linked does not coalesce a collection of descendants and it's not apparent to me why it would want to. Besides, in the context protocol a provider could identify its consumers by inspecting the received request events to determine the element that dispatched them (and in fact we'll probably want to do this for subscription retargeting in the reworked version of the protocol). Is this the kind of thing you're talking about?

To be clear, my position is just that it's not apparent to me that there actually exists a generic problem here that is relevant outside of the context protocol.

from community-protocols.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.