Overview
HybridComponent is a base class that extends ShadowComponent and provides both shadow DOM rendering with Kempo CSS styles AND light DOM rendering. Use this when you want your component to:
- Have shadow DOM with Kempo CSS for internal UI elements
- Also render content to the light DOM alongside natural children
- Combine the benefits of both shadow and light DOM
Basic Usage
Create a custom component by extending HybridComponent and implementing both render() for shadow DOM and renderLightDom() for light DOM:
import HybridComponent from './HybridComponent.js';
import { html, css } from '../lit-all.min.js';
export default class MyHybridComponent extends HybridComponent {
static properties = {
title: { type: String }
};
static styles = css`
:host {
display: block;
}
.shadow-content {
background: var(--c_primary);
color: var(--tc_on_primary);
padding: var(--spacer);
}
`;
constructor() {
super();
this.title = 'Hybrid';
}
// Shadow DOM content with Kempo CSS styles
render() {
return html`
<div class="shadow-content">
<h3>${this.title} Component</h3>
<slot name="lightRoot"></slot>
</div>
`;
}
// Light DOM content alongside natural children
renderLightDom() {
return html`
<p class="p">This is rendered to light DOM</p>
<slot></slot>
`;
}
}
customElements.define('my-hybrid-component', MyHybridComponent);
Important: The default render() method includes <slot name="lightRoot"></slot> which is where the light DOM content appears. If you override render(), make sure to include this slot.
Also Important: Always call super.updated() when overriding the updated() lifecycle method:
updated(changedProperties) {
super.updated(); // Required!
// Your custom logic here
}
When to Use
Use HybridComponent when:
- You need styled internal UI elements (buttons, headers, etc.) in shadow DOM
- You also need to render content to light DOM alongside natural children
- You want Kempo CSS styles for your component UI but need flexibility for user content
Example use cases:
- Dialog: Shadow DOM for styled dialog chrome (header, footer, overlay), light DOM for user content
- Collapsible: Shadow DOM for toggle button, light DOM for collapsible content
- SideMenu: Shadow DOM for menu structure and styling, light DOM for menu items
Use ShadowComponent instead when you only need shadow DOM.
Use LightComponent instead when you only need light DOM.
JavaScript Reference
Constructor
Extends ShadowComponent
new HybridComponent()
Creates a new HybridComponent instance with both shadow DOM (with Kempo CSS) and light DOM rendering.
Requirements
- Lit (html, render)
- ShadowComponent
Properties
lightRoot: HTMLElement
A container element with display: contents that holds the rendered light DOM content. It has slot="lightRoot" to connect it to the shadow DOM slot. Created automatically by createRenderRoot().
Methods
createRenderRoot(): Element
Creates both shadow DOM (via super.createRenderRoot()) and light DOM render containers. This method:
- Calls the parent ShadowComponent's
createRenderRoot()to set up shadow DOM with Kempo CSS - Creates a
lightRootdiv withdisplay: contentsandslot="lightRoot" - Appends
lightRootto the component element - Returns the shadow render container
updated(): void
Called automatically by Lit when the component updates. Renders the result of renderLightDom() into lightRoot. Override this method if needed, but always call super.updated().
renderLightDom(): TemplateResult
Override this method to define what should be rendered to the light DOM. Returns an empty template by default. Use Lit's html tagged template literal to return your content. Typically includes a <slot></slot> for natural children.
render(): TemplateResult
Override this method to define what should be rendered to the shadow DOM. The default implementation returns html`<slot name="lightRoot"></slot>` which displays the light DOM content. When overriding, make sure to include this slot where you want the light DOM content to appear.