A lightweight (~5.3kb) library for building Web Components, compatible with Vanilla JS and all JavaScript frameworks. This library simplifies the creation of Web Components and offers features such as using JavaScript template literals for template syntax, rerendering elements with watch, creating getter/setters with getset, property reflection with propReflect, inline events with event, custom events with emit, injecting global styles with injectStyles, and support for TypeScript.
-
JavaScript Template Literals for Template Syntax: Simplify the creation of templates using JavaScript template literals. Template literals
-
Rerender Element with Watch: Easily trigger a rerender of an element by watching for changes.
watch
-
Create Getter/Setters with getset: Define getter and setter functions for your properties.
getset
-
Create Property Reflection with propReflect: Reflect property changes to corresponding attributes.
propReflect
-
Create Inline Events with event: Attach events directly in your component's template.
event
-
Create Custom Events with emit: Emit custom events from your components.
emit
-
Inject Global Styles with injectStyles: Apply global styles for your components.
injectStyles
-
Support for TypeScript: Enjoy type safety when using Redgin with TypeScript.Support Typescript
-
Build SPAs (Single-Page Applications): Simplify the development of SPAs using Redgin.Single Page Application
Include the RedGin library in your project.
// via html
<script type="module" src="https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js"></script>
Or install it via npm:
npm i redgin
- Import the Library:
// via js
import { RedGin, watch, getset, html } from 'https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js';
// via npm
import { RedGin, watch, getset, html } from 'redgin';
- Use the Features:
// FetchApiComponent.ts
// Creating a Fetch Api Component that displays Todos using Getset, Watch
class FetchApi extends RedGin {
// Reactive properties using getset
ready = getset<boolean>(false);
todos: any;
// Initialize data from the API in the onInit lifecycle method
onInit() {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
this.todos = json;
this.ready = true;
});
}
// Render method for displaying the fetched data
render() {
return html`
${watch(['ready'],
() => this.ready ? JSON.stringify(this.todos) : html`Loading...`
)}`;
}
}
// Define the custom element 'fetch-api'
customElements.define('fetch-api', FetchApi);
- Passing data from Parent to Child component
// ParentToChildComponents.ts
class ParentComp extends RedGin {
currentItem: string = 'Laptop';
// Initialize child component with data using properties or attributes
onInit() {
// Option 1: Send data to child component using properties
const child: IChild = this.shadowRoot?.querySelector('child-comp')!;
child.item = this.currentItem;
}
// Render method for the parent component
render() {
return html`
<child-comp></child-comp>
<!-- Option 2: Send data to child component using attributes -->
<child2-comp item="${this.currentItem}"></child2-comp>
`;
}
}
- Passing data from Child to Parent component
// ParentChildComponents.ts
// Child component for emitting a custom event
class ChildComp extends RedGin {
render() {
return html`
<button ${event('click', () => emit.call(this, 'newItem', 'added New Item?'))}>
<slot>Add to parent's list</slot>
</button>
`;
}
}
// Parent component for receiving the custom event
class ParentComp extends RedGin {
render() {
return html`
<child-comp
${event('newItem', (e: CustomEvent) => console.log(`Received child data: ${e.detail}`))}>
Get Child Data?
</child-comp>
`;
}
}
- Creating a Reactive button
// ReactiveButton.ts
class ReactiveButton extends RedGin {
// Reactive property using propReflect
message = propReflect<string>('Hello, World!');
// Observed attributes for the component
static observedAttributes = ['message'];
// Render method for the component
render() {
// Use watch to trigger a rerender when 'message' changes
return html`${watch(['message'], () => html`
<button type="button">${this.message}</button>
`)}
`;
}
}
- For Loop through the list of Products
// ProductListRenderer.ts
// For Loop through the List of Products
class ProductListRenderer extends RedGin {
// Reactive property using getset
products = getset<IProduct[]>([
{ id: 1, name: 'Laptop' },
{ id: 2, name: 'Camera' },
]);
// Render method for displaying the list of products
render() {
return html`
<ul>
${watch(['products'], () =>
this.products.map(product =>
html`<li>${product.id} - ${product.name}</li>`
)
)}
</ul>`;
}
}
More
Install extension inline-html
render() {
return html`<div>with syntax highlighted</div>`
}
https://web.dev/custom-elements-best-practices/
git clone [email protected]:josnin/redgin.git
cd ~/Documents/redgin/
npm install
npm run dev
Need help? Open an issue in: ISSUES
Want to improve and add feature? Fork the repo, add your changes and send a pull request.