Based on my first proof of concepts (see my cute tab-system), I've concluded the following. Written as a guideline, but of course up for debate.
Guidelines for custom element development
Creation callbacks happen parent-first. If during a parent's callback phase, you need to manipulate or read from child elements, you cannot use their custom APIs yet. During creation, you can however use your own API safely. To create a consistent code-style and to ensure the above issue does not arise, the following rules must be followed:
Use an outer parent's createdCallback hook to sanity-check the entire existing structure and augment it if necessary. Some child elements may be reasonably left out by users (eg: <thead> and <tbody> in a <table>). The component should not break when this is the case.
Component event hooks may be implemented directly on the prototype, just like any other public APIs. They may use core DOM APIs on themselves or related DOM elements.
Custom public APIs may never use other custom public APIs on other elements but "this". Make helper functions whenever you need to reuse logic. These helper functions should take inputs, and not depend on the this keyword.
Because users are free to modify the DOM directly, any reference property to a child or parent, should be a getter method and cannot be a cached value. For DOM Elements it's common to have getters (form.elements, select.options, etc) to access related elements. We can emulate this.
When behavior is linked to attributes, implement the behaviors in the attributeChangedCallback hook so that it's triggered both through JS API as well as through DOM APIs called by the user.
Be aware that elements may be disconnected from the document or their parent (even if only temporarily). Don't insist on there being parent or child relations if none are required for the operation you're doing. If you want to access siblings, as long as you have a parent, you're good. You shouldn't care if the parent is a documentFragment or the element it typically would be.
Based on my first proof of concepts (see my cute tab-system), I've concluded the following. Written as a guideline, but of course up for debate.
Guidelines for custom element development
Creation callbacks happen parent-first. If during a parent's callback phase, you need to manipulate or read from child elements, you cannot use their custom APIs yet. During creation, you can however use your own API safely. To create a consistent code-style and to ensure the above issue does not arise, the following rules must be followed:
createdCallback
hook to sanity-check the entire existing structure and augment it if necessary. Some child elements may be reasonably left out by users (eg:<thead>
and<tbody>
in a<table>
). The component should not break when this is the case.this
keyword.attributeChangedCallback
hook so that it's triggered both through JS API as well as through DOM APIs called by the user.