Installation
HTML-COMPO.js is a lightweight library for creating reusable HTML components without any build tools or complex setup.
<script src="https://cdn.jsdelivr.net/npm/html-compo@latest/src/main.js"></script>
npm install html-compo
Then include in your project:
import 'html-compo';
Download the latest version from GitHub and include it in your project:
<script src="path/to/html-compo.js"></script>
Quick Start
Get started with HTML-COMPO.js in just a few steps:
1. Include the library
<script src="https://cdn.jsdelivr.net/npm/html-compo@latest/src/main.js"></script>
2. Define your components
<html-components> <user-card> <div class="card"> <h3>@{self.data}</h3> </div> </user-card> </html-components>
3. Use your components
<user-card>John Doe</user-card> <user-card>Jane Smith</user-card>
Basic Usage
Component Definition Container
Use <html-components>
or the shorter <h-c>
tag to define your components:
<html-components> <my-button> <button class="btn">@{self.data}</button> </my-button> </html-components> <!-- Alternative shorter syntax --> <h-c> <my-button> <button class="btn">@{self.data}</button> </my-button> </h-c>
Template Variables
Use @{variable}
syntax to insert dynamic content:
@{self.data}
The content inside the component tag when used
@{self.componentName}
The tag name of the component
@{attributeName}
Values from component attributes (when using compo-attrs)
Basic Example
<greeting-card>Hello, World!</greeting-card> <greeting-card>Welcome to HTML-COMPO.js</greeting-card> <html-components> <greeting-card> <div class="greeting"> <h2>🎉 @{self.data} 🎉</h2> <p>This is a @{self.componentName} component!</p> </div> </greeting-card> </html-components>
Component Attributes
Using compo-attrs
The compo-attrs
attribute allows you to specify which attributes should be passed as variables to your component template:
<user-profile name="John Doe" email="[email protected]" role="Admin"></user-profile> <user-profile name="Jane Smith" email="[email protected]" role="User"></user-profile> <html-components> <user-profile compo-attrs="name,email,role"> <div class="profile"> <h3>@{name}</h3> <p>Email: @{email}</p> <p>Role: @{role}</p> </div> </user-profile> </html-components>
Default Attribute Values
You can provide default values for attributes using the attributeName=defaultValue
syntax:
<product-card name="Laptop" price="999"></product-card> <product-card name="Phone"></product-card> <!-- Uses default price --> <html-components> <product-card compo-attrs="name,price=599"> <div class="product"> <h4>@{name}</h4> <p>Price: $@{price}</p> </div> </product-card> </html-components>
Shadow DOM Support
HTML-COMPO.js supports Shadow DOM encapsulation using the fragment="true"
attribute:
<style> .shadow-demo { color: red; font-size: 20px; } </style> <shadow-component>This text won't be affected by external styles</shadow-component> <div class="shadow-demo">This text will be red and large</div> <html-components> <shadow-component fragment="true"> <style> .shadow-demo { color: blue; font-size: 14px; } </style> <div class="shadow-demo">@{self.data}</div> </shadow-component> </html-components>
API Reference
Global API
HTML-COMPO.js exposes a global htmlCompo
object with the following methods:
Gets a component instance by its reference attribute.
Returns: An HtmlCompoFunc instance or null if not found
HtmlCompoFunc Class
Returned by getComponent()
, provides methods to manipulate components:
Gets or sets the HTML content of the component.
Gets or sets an attribute of the component.
Using Component References
<my-counter ref="counter1" count="0"></my-counter> <button onclick="incrementCounter()">Increment</button> <script> function incrementCounter() { const counter = htmlCompo.getComponent('counter1'); if (counter) { const currentCount = parseInt(counter.attr('count')) + 1; counter.attr('count', currentCount); counter.html(`Count: ${currentCount}`); } } </script> <html-components> <my-counter compo-attrs="count"> Count: @{count} </my-counter> </html-components>
Advanced Examples
Todo List Component
<todo-item task="Buy groceries" completed="false"></todo-item> <todo-item task="Walk the dog" completed="true"></todo-item> <html-components> <todo-item compo-attrs="task,completed=false"> <div class="todo-item" style="margin: 10px 0; padding: 10px; border: 1px solid #ddd;"> <input type="checkbox" @{completed === 'true' ? 'checked' : ''}> <span style="@{completed === 'true' ? 'text-decoration: line-through; color: #999;' : ''}"> @{task} </span> </div> </todo-item> </html-components>
Card Component with Slots
<info-card title="Welcome" type="success"> This is a success message with <strong>HTML content</strong>! </info-card> <info-card title="Warning" type="warning"> Please check your input carefully. </info-card> <html-components> <info-card compo-attrs="title,type=info"> <div style="border: 2px solid; padding: 15px; margin: 10px 0; border-radius: 5px; border-color: @{type === 'success' ? '#4caf50' : type === 'warning' ? '#ff9800' : '#2196f3'}; background-color: @{type === 'success' ? '#e8f5e8' : type === 'warning' ? '#fff3e0' : '#e3f2fd'};"> <h4 style="margin: 0 0 10px 0; color: @{type === 'success' ? '#2e7d32' : type === 'warning' ? '#ef6c00' : '#1565c0'};"> @{title} </h4> <div>@{self.data}</div> </div> </info-card> </html-components>
Navigation Menu
<nav-menu> <nav-item href="#home">Home</nav-item> <nav-item href="#about">About</nav-item> <nav-item href="#contact" active="true">Contact</nav-item> </nav-menu> <html-components> <nav-menu> <ul style="list-style: none; display: flex; gap: 0; margin: 0; padding: 0; background: #333;"> @{self.data} </ul> </nav-menu> <nav-item compo-attrs="href,active=false"> <li> <a href="@{href}" style="display: block; padding: 15px 20px; color: white; text-decoration: none; background: @{active === 'true' ? '#555' : 'transparent'}; border-bottom: @{active === 'true' ? '3px solid #007bff' : 'none'};"> @{self.data} </a> </li> </nav-item> </html-components>
TypeScript Support
HTML-COMPO.js includes full TypeScript support with type definitions and a TypeScript source version.
Installation with TypeScript
npm install html-compo npm install -D typescript
Type Definitions
The library provides comprehensive type definitions:
interface HtmlCompoAPI { getComponent(reference: string): HtmlCompoFunc | null; } declare global { interface Window { htmlCompo: HtmlCompoAPI; } } class HtmlCompoFunc { html(): string; html(content: string): void; attr(name: string): string | null; attr(name: string, value: string): void; }
Usage in TypeScript
// Type-safe component access const component = window.htmlCompo.getComponent('my-ref'); if (component) { // TypeScript knows these methods exist and their signatures const content: string = component.html(); component.attr('class', 'new-class'); }
Best Practices
📝 Naming Convention
Use kebab-case for component names (e.g., user-card
, nav-item
)
🎯 Keep Components Simple
Each component should have a single responsibility and be reusable
📦 Use Attributes Wisely
Leverage compo-attrs
for configurable components with sensible defaults
🔒 Consider Shadow DOM
Use fragment="true"
when you need style encapsulation
🏷️ Use References
Add ref
attributes to components you need to manipulate with JavaScript
⚡ Performance
Define components early in your HTML for optimal performance