defineComponent
Register a custom HTML element that renders a template when encountered in the DOM.
Signature
typescript
function defineComponent<P extends Record<string, any>>(
tagName: string,
renderer: ComponentRenderer<P>,
): void
type ComponentRenderer<P> = (
props: P,
slots: Record<string, Node[]>,
) => TemplateBasic Component
typescript
import { defineComponent, html } from "croft";
defineComponent("my-greeting", (props, slots) => {
return html`<h1>Hello, ${props.name}!</h1>`;
});Usage in Templates
typescript
html`<my-greeting name="World"></my-greeting>`;
// Renders: <h1>Hello, World!</h1>Typed Props
typescript
interface ButtonProps {
variant: string;
label: string;
}
defineComponent<ButtonProps>("my-button", (props, slots) => {
return html`
<button class="btn btn-${props.variant}">
${slots.default?.length ? slots.default : props.label}
</button>
`;
});Plugin Mount
Components can also be registered in groups via the plugin mount system:
typescript
import Croft from "croft";
Croft.mount("components", {
"my-button": (props: any) =>
html`<button class=${props.variant}>${props.label}</button>`,
"my-badge": (props: any) =>
html`<span class=${props.variant}>${props.label}</span>`,
});removeComponent
typescript
import { removeComponent } from "croft";
removeComponent("my-greeting");How It Works
resolveComponentswalks the DOM top-down, finding registered custom elements.- Attributes are collected and resolved into a props object.
- Child nodes are extracted and bucketed into named slots.
- Slot children are processed through directives and component resolution.
- The render function is called with
(props, slots). - The returned Template is compiled and replaces the custom element.