custom-elements-manifest
custom-elements-manifest copied to clipboard
Allowed children for slots
Both standard components (e.g. table, tr, td, dl, dd) and web components (e.g. tab-panels, tab-panel) have implicit constraints on what elements are allowed as children, and also what are allowed as parents.
I would propose that a slot description should also include a way to codify this.
For example:
export interface Slot {
/**
* The slot name, or the empty string for an unnamed slot.
*/
name: string;
/**
* A markdown summary suitable for display in a listing.
*/
summary?: string;
/**
* A markdown description.
*/
description?: string;
/**
* A set of CSS selectors for allowable children
*/
allowedChildren?: string[];
}
#55
I also would need that as info for my designer (https://github.com/node-projects/web-component-designer) I have tab-control in my customer application, wich only allows tab-item elements as children. so i could constraint the designer to allow adding the wrong ones
CSS selectors might be insufficient here.
The HTML specification has a concept of "content-models" to express this for built-in elements: https://html.spec.whatwg.org/multipage/dom.html#content-models
This has categories like "Interactive content" and "Palpable content" that would only be describable with large lists of tag name selectors.
And I don't see how class selectors and attribute selectors will be generally useful for this feature. I don't know of elements that say that a slot can only contain with a certain class.
I have seen elements that can only accept things like: specific elements, a single element, elements that have implement a certain JS interface, and elements that fire or listen to specific events.
I'm not sure how we describe all that, and it's not easily machine generated. I think we should collect examples of child restrictions first.
I would like to add that we've found use cases for both directions of restrictions:
validChildrenvalidParents
It seems that the validParents restriction is more important than the validChildren restriction. Components should be written in a way to not cause problems when they have unexpected children, but there are certain components that really need to be used in the right parents.
And I don't see how class selectors and attribute selectors will be generally useful for this feature. I don't know of elements that say that a slot can only contain with a certain class.
This is a really good argument against css selectors!
It might make sense to support a "CSS selector inspired" syntax with wildcard *, tag names tr and comma separated values td, th.
I'm not sure how we describe all that, and it's not easily machine generated. I think we should collect examples of child restrictions first.
A great place to look for inspiration:
- Restrictions in WYSIWYG editors such as:
- PromiseMirror schema - restricts editing and clipboard pasting to enforce some of the basic HTML rules, and is extensible for custom elements
- TipTap schema - based on ProseMirror
- Raisins schema - restricts and validates block-level values, only uses custom elements
- The HTML spec
- Can we model a
tablewith all the related elements (td, tr, th, thead, tfoot, colgroup) using this vocabulary?
- Libraries that require structure
- Tabs in carbon
- Tabs in Blaze UI
- Tabs in Shoelace
- We have been using this at SaaSquatch (now Impact.com) for building frontend components with allowed children and allowed parents
There could also be a restriction of how many elements could be added, and how many of wich type. I also don't think we can solve all cases with this. But a good 95% would give much better designer experience.
Also, there could be named slots, maybe we also should have a way wich names exit and wich elements could be used inside of them.
At hte moment I solved it like this in my designer (https://node-projects.github.io/web-component-designer-demo/index.html) - if a custom-element has a slot, it could be a container, if not, not
if a custom-element has a slot, it could be a container, if not, not
This isn't true always either, because elements without a shadow root show their contents, and even with a shadow root and no slot, the child elements can hold state, fire events, etc.