A belated Happy New Year!
As you probably know, the claim to fame of the shadow DOM is the ability to “encapsulate” CSS, i.e., to prevent both inside-out and outside-in style leakage across the confines of a given shadow DOM.
The NinjaShadow component can (more or less) be regarded as a regular Form. However, when you set the ‘html’ property of a NinjaShadow instance, that HTML automatically gets wrapped in its own shadow DOM (specifically, the DOM node of the component’s Anvil Form gets an open shadow DOM attached to it). This means that you can define “component-level encapsulated” styles within the component’s HTML. To do this, just include a style tag in the component’s HTML and prefix all CSS selectors with ‘:host’. Styles defined in this way only apply to the component’s HTML. If left at this, the component’s HTML is not affected by any global stylesheets. Global stylesheets can, however, be “brought in” by including link tags with appropriate references to global (or non-global for that matter) stylesheets in the component’s HTML (the demo app showcases this).
HTML is typically not much fun if you cannot access the elements (e.g., to add event listeners and to dynamically create content). Accessing the component’s HTML elements can be done via the component’s ‘root’ property (the demo app also does this).
Component and demo:
In a previous iteration of the component, I did in fact allow for inclusion of anvil-slot elements in the shadow DOM HTML. It did require overloading the HtmlTemplate-inherited methods, ‘add_component’, ‘get_component’, and ‘clear’ – and to simultaneously control added Anvil components in the slots as well as in internal containers. It actually worked. However, some properties of Anvil’s UI components are controlled via DOM classes – and these of course do not readily penetrate the shadow DOM (which is close to the entire rationale for using a shadow DOM in the first place). Long story short, the benefits of adding this extra code (to an otherwise simple component) didn’t really make sense to me, so I took it out.