Overview
Purpose: lets a list-like component obtain its list items from its DOM content. It expects the component to identify its HTML "contents", and then impose some restrictions on those contents to determine which of those HTML elements are actually interesting to use as the items in the list.
This mixin primarily works in the middle of the Elix render pipeline:
events → methods → setState ➞ render DOM → post-render
Expects the component to provide:
[internal.state].content
member containing a flattened array ofNode
elements. You can use SlotContentMixin for this purpose.
Provides the component with:
[internal.state].items
member containing the content elements that should be treated as list items. See Obtaining items from content below.
Usage
import ContentItemsMixin from "elix/src/base/ContentItemsMixin.js";
class MyElement extends ContentItemsMixin(HTMLElement) {}
Items differ from raw element contents in several ways:
- They are often referenced via index.
- They may have a selection state.
- It's common to do work to initialize the appearance or state of a new item.
- Text nodes (which are often whitespace) are ignored.
- Invisible child elements are filtered out and not counted as items.
Instances of invisible
Node
subclasses such asComment
andProcessingInstruction
are filtered out, as are invisible auxiliary elements include link, script, style, and template elements. This filtering ensures that those auxiliary elements can be used in markup inside of a list without being treated as list items.
This mixin is designed to address the Gold Standard checklist criteria for Child Independence (Can you use the component with a wide range of child element types?) and Auxiliary Content (Does the component permit the use of child elements that perform auxiliary functions?). To meet those criteria, it is better for a component to filter out what it doesn't want using ContentItemsMixin
than to exclusively filter in only a specific type of element (using, say, querySelectorAll
).
Example
<my-element>
<style>
div {
color: gray;
}
</style>
<div>One</div>
<div>Two</div>
<div>Three</div>
</my-element>
If this element uses ContentItemsMixin
, its items
property will return the three div
elements, and filter out the whitespace text nodes and the invisible style
element.
Obtaining items from content
ContentItemsMixin
expects a component to define a state member [internal.state].content
containing the raw set of HTML elements the component contains. How a component interprets "contains" can vary, but a common definition would be the component's light DOM children. In that common case, SlotContentMixin can be used to define [internal.state].content
as the light DOM children assigned to the component's default slot
.
Other definitions of content are possible. Your component could, for example, define [internal.state].content
to only extract nodes assigned to a particular named slot
, or the children of a node in the component's shadow tree, or a set of nodes not actually in the DOM.
ContentItemsMixin
manages a state member called [internal.state].items
that filters the results of [internal.state].content
. This is an array of items designed for use with SingleSelectAPIMixin and its companion mixins. ContentItemsMixin uses the helper function content.substantiveElements to subtract out any nodes in [internal.state].content
that would not normally be visible to the user.
Rendering updates to items
List-like components often need to update their light DOM content too, e.g., to add attributes or classes to the nodes for list items. A component can render state changes to its items in its internal.render method. See SingleSelectAPIMixin for an example.
API
Used by class SlotItemsMixin.