Skip to content

rodiniz/webcomponents

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

105 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@diniz/webcomponents

npm version

A lightweight, framework-agnostic Web Components library with everything you need to build modern web apps β€” without the bloat.


Why @diniz/webcomponents?

Most web component libraries force you into a choice: either you get a polished design system or you get app-level primitives like routing and state management.

@diniz/webcomponents gives you both β€” in a tiny, dependency-free package.

Feature @diniz/webcomponents Shoelace Material Web Lightning Web Runtime
Routing with lazy loading βœ… Built-in ❌ ❌ ❌
State management βœ… Store + Signals ❌ ❌ ❌
Theme system βœ… CSS Variables + Custom βœ… βœ… βœ…
Bundle size ~41KB gzipped ~84KB ~50KB ~100KB+
Framework agnostic βœ… βœ… βœ… ❌ Salesforce-only
TypeScript-first βœ… βœ… βœ… βœ…
Storybook docs βœ… βœ… βœ… ❌

Quick Start

npm install @diniz/webcomponents

Component Usage

<script type="module">
  import '@diniz/webcomponents';
</script>

<ui-button variant="primary" size="lg">
  Get Started
</ui-button>

<ui-input 
  label="Email" 
  type="email" 
  placeholder="you@example.com"
  required
></ui-input>

<ui-table id="users"></ui-table>

<script type="module">
  const table = document.getElementById('users');
  table.columns = [
    { key: 'name', label: 'Name', sortable: true },
    { key: 'email', label: 'Email' },
    { key: 'actions', label: 'Actions', actions: { edit: true, delete: true } }
  ];
  table.rows = [
    { name: 'John Doe', email: 'john@example.com' },
    { name: 'Jane Smith', email: 'jane@example.com' }
  ];
</script>

Router & SPA Setup

Build a single-page application with built-in routing and lazy loading:

1. Create HTML Entry Point

Create index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My App</title>
  <link rel="stylesheet" href="/src/styles/theme.css">
</head>
<body>
  <nav>
    <a href="/" data-link>Home</a>
    <a href="/about" data-link>About</a>
    <a href="/users" data-link>Users</a>
  </nav>

  <!-- Router outlet - components render here -->
  <div id="app"></div>

  <!-- Vite module entry point -->
  <script type="module" src="/src/main.ts"></script>
</body>
</html>

2. Create Main TypeScript Module

Create src/main.ts:

import '@diniz/webcomponents';
import { createRouter, applyTheme } from '@diniz/webcomponents';

// Define routes with lazy-loaded components
const routes = [
  {
    path: '/',
    component: 'home-page',
    load: () => import('./pages/home')
  },
  {
    path: '/about',
    component: 'about-page',
    load: () => import('./pages/about')
  },
  {
    path: '/users',
    component: 'users-page',
    load: () => import('./pages/users')
  },
  {
    path: '/users/:id',
    component: 'user-detail-page',
    load: () => import('./pages/user-detail')
  }
];

// Create router
const router = createRouter(routes);

// Apply theme
applyTheme('shadcn');

// Initialize router on page load
document.addEventListener('DOMContentLoaded', () => router());

3. Create Page Components

Create src/pages/home.ts:

import { LitComponent } from '@diniz/webcomponents';
import { html } from 'lit';

export class HomePage extends LitComponent {
  render() {
    return html`
      <div class="page">
        <h1>Welcome Home</h1>
        <p>This is the home page.</p>
        <ui-button @click=${() => this.navigate('/about')}>
          Go to About
        </ui-button>
      </div>
    `;
  }

  private navigate(path: string) {
    history.pushState(null, '', path);
    window.dispatchEvent(new PopStateEvent('popstate'));
  }
}

customElements.define('home-page', HomePage);

Create src/pages/users.ts:

import { LitComponent } from '@diniz/webcomponents';
import { html } from 'lit';

export class UsersPage extends LitComponent {
  private users = [
    { id: 1, name: 'John Doe', email: 'john@example.com' },
    { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
  ];

  render() {
    return html`
      <div class="page">
        <h1>Users</h1>
        <ui-table
          .columns=${[
            { key: 'name', label: 'Name', sortable: true },
            { key: 'email', label: 'Email' }
          ]}
          .rows=${this.users}
        ></ui-table>
      </div>
    `;
  }
}

customElements.define('users-page', UsersPage);

Create src/pages/user-detail.ts:

import { LitComponent } from '@diniz/webcomponents';
import { html } from 'lit';
import { getPathParams } from '@diniz/webcomponents';

export class UserDetailPage extends LitComponent {
  private userId: string | null = null;

  connectedCallback() {
    super.connectedCallback();
    const params = getPathParams('/users/:id', location.pathname);
    this.userId = params?.id ?? null;
  }

  render() {
    return html`
      <div class="page">
        <h1>User Details</h1>
        <p>User ID: ${this.userId}</p>
        <ui-button @click=${() => history.back()}>
          Go Back
        </ui-button>
      </div>
    `;
  }
}

customElements.define('user-detail-page', UserDetailPage);

4. Vite Configuration

Update vite.config.ts:

import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    port: 5173,
    open: true
  },
  build: {
    target: 'esnext',
    outDir: 'dist'
  }
});

5. Run Development Server

npm run dev

The Vite dev server will:

  • Serve index.html as entry point
  • Handle TypeScript compilation automatically
  • Lazy load page modules on navigation
  • Support hot module replacement

Key Features

  • Lazy Loading β€” Pages load only when navigated to
  • No Build Step for Components β€” Components render dynamically
  • Type Safety β€” Full TypeScript support
  • Real-time HMR β€” See changes instantly during development
  • Automatic Bundling β€” Vite handles optimization

Complete Example Structure

src/
β”œβ”€β”€ main.ts           # Router setup
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ home.ts       # HomePage component
β”‚   β”œβ”€β”€ about.ts      # AboutPage component
β”‚   β”œβ”€β”€ users.ts      # UsersPage component
β”‚   └── user-detail.ts # UserDetailPage component
└── styles/
    └── theme.css     # Global theme
index.html           # Entry point

See Router Documentation for advanced features like route guards, path parameters, and base path configuration.


What's Included

Icons: This library uses Feather Icons for all iconography.

πŸ“‹ Form Components

  • ui-input β€” Text, email, password with validation, icons, custom rules
  • ui-select β€” Searchable dropdowns
  • ui-checkbox β€” Custom styled checkboxes
  • ui-radio β€” Radio buttons with descriptions
  • ui-radio-group β€” Grouped radios with card variant
  • ui-toggle-switch β€” iOS-style toggles

🧩 Layout Components

  • ui-card β€” Versatile card with slots, variants, shadows
  • ui-accordion β€” Collapsible sections
  • ui-tabs β€” Animated tab navigation
  • ui-modal β€” Accessible dialogs
  • ui-sidebar β€” Navigation sidebar with icons
  • ui-top-bar β€” Page header with actions

πŸ“Š Data Components

  • ui-table β€” Sortable, resizable, expandable rows, actions
  • ui-treeview β€” Hierarchical data with lazy loading
  • ui-pagination β€” Page navigation
  • ui-picklist β€” Dual-list selection

🎯 Feedback

  • ui-toast β€” Success, error, warning, info notifications
  • ui-spinner β€” Loading indicators
  • ui-tooltip β€” Hover/click tooltips
  • ui-stepper β€” Multi-step flows

πŸ”§ Utilities

  • ui-button β€” Variants, sizes, icons, loading states
  • ui-link β€” Styled anchor links
  • ui-dropdown β€” Menu dropdowns
  • ui-date-picker β€” Calendar date selection
  • ui-upload β€” File uploads

βš™οΈ App Primitives (Unique!)

import { createRouter, createStore, applyTheme } from '@diniz/webcomponents';

// Built-in router with lazy loading
const router = createRouter([
  { path: '/', component: 'home-page', load: () => import('./pages/home') },
  { path: '/users/:id', component: 'user-page', load: () => import('./pages/user'), guards: [authGuard] }
]);

// Lightweight state management
const store = createStore({ user: null });
const { state, setState } = store;
setState('user', { name: 'John' });

// Multiple themes
applyTheme('shadcn'); // or 'zinc', 'rose', 'blue', 'green', 'orange', 'violet'

// Custom themes
registerCustomTheme({ name: 'my-app', url: '/themes/my-app.css' });
await applyTheme('my-app');

Comparison with Alternatives

vs Shoelace

@diniz/webcomponents Shoelace
Routing βœ… Native ❌ External
State management βœ… Native ❌ External
Bundle size ~41KB ~84KB
Theming CSS variables CSS variables
Dependencies None (lit only) None (lit only)

vs Material Web (Google)

@diniz/webcomponents Material Web
Routing βœ… Built-in ❌ External
State management βœ… Native ❌ External
Bundle size ~41KB ~50KB
Design Clean, modern Material Design 3
Customization Full CSS control Limited theming

vs Salesforce Lightning Web Runtime

@diniz/webcomponents LWR
Routing βœ… Universal ❌ Salesforce-only
State management βœ… Universal ❌ Salesforce-only
Bundle size ~41KB ~100KB+
Platform Any framework Salesforce only
Open source βœ… MIT ❌ Proprietary

vs Building from Scratch

@diniz/webcomponents Custom
Time to first component 5 minutes 2-3 days
Accessibility βœ… ARIA, keyboard You decide
Theming βœ… Ready Build yourself
Routing βœ… Included Build yourself
State βœ… Included Build yourself
Testing βœ… Included Build yourself

Why It's Different

Most web component libraries are just component collections. They give you buttons and inputs but leave you to figure out:

  • How to navigate between pages
  • How to manage application state
  • How to theme everything consistently

@diniz/webcomponents includes all the pieces you need for a complete app:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    @diniz/webcomponents                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Components    β”‚  Routing    β”‚  State    β”‚  Theming       β”‚
β”‚  ───────────   β”‚  ───────    β”‚  ─────    β”‚  ───────       β”‚
β”‚  β€’ ui-button   β”‚  β€’ SPA      β”‚  β€’ Store   β”‚  β€’ CSS vars    β”‚
β”‚  β€’ ui-input    β”‚  β€’ Lazy     β”‚  β€’ Signals β”‚  β€’ 7 themes    β”‚
β”‚  β€’ ui-table    β”‚  β€’ Guards   β”‚            β”‚  β€’ Custom      β”‚
β”‚  β€’ ui-modal    β”‚             β”‚            β”‚                β”‚
β”‚  β€’ ui-toast    β”‚             β”‚            β”‚                β”‚
β”‚  β€’ ...20+ more β”‚             β”‚            β”‚                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Documentation & Demo


Framework Integration

Works with anything that supports Custom Elements:

// Vanilla TypeScript
import '@diniz/webcomponents';

// React
import '@diniz/webcomponents';
<ui-button>Click me</ui-button>;

// Vue  
import '@diniz/webcomponents';
<ui-button>Click me</ui-button>;

// Svelte
import '@diniz/webcomponents';
<ui-button>Click me</ui-button>;

AI Agent Skills

The library includes comprehensive AI agent skills for developers and AI assistants working with the components.

Using Skills with VS Code Copilot

The skills are available for use with VS Code's GitHub Copilot:

  1. Install the skill β€” It's automatically available when this project is open

  2. Ask questions β€” Use natural language queries like:

    • "How do I create a table with sorting and pagination?"
    • "Show me how to validate form inputs"
    • "Create a sidebar with custom theme colors"
    • "How do I use the HTTP client?"
  3. Get guidance β€” The skill provides:

    • Component usage examples
    • Validation patterns
    • Theming and styling guidance
    • API integration patterns
    • Best practices
    • Type definitions

Skill Features

  • Component Reference β€” Complete API for 25+ components
  • Code Examples β€” Copy-paste ready examples for all components
  • Patterns β€” Common patterns for forms, tables, navigation, etc.
  • Validation β€” Form validation and error handling patterns
  • Theming β€” Theme system and customization guide
  • HTTP Integration β€” API client usage and patterns
  • State Management β€” Built-in store and signals guide
  • Routing β€” Navigation and page management patterns

Example Usage

# Ask Copilot to help with a component
# "I need a data table that loads from an API with pagination and sorting"

# The skill provides:
# βœ… Complete HTML/JS example
# βœ… API integration code
# βœ… Event handling
# βœ… Error handling patterns
# βœ… TypeScript types

License

MIT β€” use it anywhere.

About

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors