@design.estate/dees-wcctools

Web Component Development Tools - A powerful framework for building, testing, and documenting web components

Overview

@design.estate/dees-wcctools provides a comprehensive development environment for web components, featuring:

  • 🎨 Interactive component catalogue with live preview
  • 🔧 Real-time property editing
  • 🌓 Theme switching (light/dark modes)
  • 📱 Responsive viewport testing
  • 🧪 Advanced demo tools for component testing
  • 🚀 Zero-config setup with TypeScript and Lit support

Installation

# Using npm
npm install @design.estate/dees-wcctools --save-dev

# Using pnpm (recommended)
pnpm add -D @design.estate/dees-wcctools

Quick Start

1. Create Your Component

import { DeesElement, customElement, html, css, property } from '@design.estate/dees-element';

@customElement('my-button')
export class MyButton extends DeesElement {
  // Define a demo for the catalogue
  public static demo = () => html`
    <my-button .label=${'Click me!'} .variant=${'primary'}></my-button>
  `;

  @property({ type: String })
  public label: string = 'Button';

  @property({ type: String })
  public variant: 'primary' | 'secondary' = 'primary';

  public static styles = [
    css`
      :host {
        display: inline-block;
      }
      button {
        padding: 8px 16px;
        border-radius: 4px;
        border: none;
        font-size: 14px;
        cursor: pointer;
        transition: all 0.3s;
      }
      button.primary {
        background: #007bff;
        color: white;
      }
      button.secondary {
        background: #6c757d;
        color: white;
      }
      button:hover {
        opacity: 0.9;
      }
    `
  ];

  public render() {
    return html`
      <button class="${this.variant}">
        ${this.label}
      </button>
    `;
  }
}

2. Set Up Your Catalogue

// catalogue.ts
import { setupWccTools } from '@design.estate/dees-wcctools';
import { html } from 'lit';

// Import your components
import './components/my-button.js';
import './components/my-card.js';

// Define elements for the catalogue
const elements = {
  'my-button': MyButton,
  'my-card': MyCard,
};

// Optionally define pages
const pages = {
  'home': () => html`
    <div style="padding: 20px;">
      <h1>Welcome to My Component Library</h1>
      <p>Browse components using the sidebar.</p>
    </div>
  `,
  'getting-started': () => html`
    <div style="padding: 20px;">
      <h2>Getting Started</h2>
      <p>Installation and usage instructions...</p>
    </div>
  `,
};

// Initialize the catalogue
setupWccTools(elements, pages);

3. Create an HTML Entry Point

<!DOCTYPE html>
<html>
<head>
  <title>Component Catalogue</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 0;">
  <script type="module" src="./catalogue.js"></script>
</body>
</html>

Features

🎯 Live Property Editing

The properties panel automatically detects and allows editing of:

  • String properties with text inputs
  • Number properties with number inputs
  • Boolean properties with checkboxes
  • Enum properties with select dropdowns
  • Object and Array properties (read-only display)

📱 Viewport Testing

Test your components across different screen sizes:

  • Phone (320px width)
  • Phablet (600px width)
  • Tablet (768px width)
  • Desktop (full width)

🌓 Theme Support

Components automatically adapt to light/dark themes using the goBright property:

public render() {
  return html`
    <div class="${this.goBright ? 'light-theme' : 'dark-theme'}">
      <!-- Your component content -->
    </div>
  `;
}

Or use CSS custom properties:

import { cssManager } from '@design.estate/dees-element';

public static styles = [
  css`
    :host {
      color: ${cssManager.bdTheme('#000', '#fff')};
      background: ${cssManager.bdTheme('#fff', '#000')};
    }
  `
];

🧪 Advanced Demo Tools

The demo tools provide enhanced testing capabilities:

import * as demoTools from '@design.estate/dees-wcctools/demotools';

@customElement('my-component')
export class MyComponent extends DeesElement {
  public static demo = () => html`
    <dees-demowrapper .runAfterRender=${async (wrapper) => {
      // Use querySelector to find specific elements
      const myComponent = wrapper.querySelector('my-component') as MyComponent;
      console.log('Component found:', myComponent);
      
      // Access all children via wrapper.children
      console.log('Total children:', wrapper.children.length);
      
      // Use querySelectorAll for multiple elements
      const allDivs = wrapper.querySelectorAll('div');
      console.log('Found divs:', allDivs.length);
      
      // Simulate user interactions
      myComponent.value = 'Test value';
      await myComponent.updateComplete;
      
      // Work with all children
      Array.from(wrapper.children).forEach((child, index) => {
        console.log(`Child ${index}:`, child.tagName);
      });
    }}>
      <my-component></my-component>
      <div>Additional content</div>
    </dees-demowrapper>
  `;
}

🎭 Container Queries Support

Components can respond to their container size:

public static styles = [
  css`
    @container wccToolsViewport (min-width: 768px) {
      :host {
        flex-direction: row;
      }
    }
    
    @container wccToolsViewport (max-width: 767px) {
      :host {
        flex-direction: column;
      }
    }
  `
];

Component Guidelines

Required for Catalogue Display

  1. Components must expose a static demo property returning a Lit template
  2. Use @property() decorators for properties you want to be editable
  3. Export component classes for proper detection

Best Practices

@customElement('best-practice-component')
export class BestPracticeComponent extends DeesElement {
  // ✅ Static demo property
  public static demo = () => html`
    <best-practice-component 
      .complexProp=${{ key: 'value' }}
      simpleAttribute="test"
    ></best-practice-component>
  `;

  // ✅ Typed properties with defaults
  @property({ type: String })
  public title: string = 'Default Title';

  // ✅ Complex property without attribute
  @property({ attribute: false })
  public complexProp: { key: string } = { key: 'default' };

  // ✅ Enum with proper typing
  @property({ type: String })
  public variant: 'small' | 'medium' | 'large' = 'medium';
}

URL Routing

The catalogue uses URL routing for deep linking:

/wcctools-route/:type/:name/:viewport/:theme

Example:
/wcctools-route/element/my-button/desktop/dark
/wcctools-route/page/home/tablet/bright

Development Workflow

Build and Watch

{
  "scripts": {
    "build": "tsbuild tsfolders --allowimplicitany && tsbundle element",
    "watch": "tswatch element",
    "serve": "http-server ./dist"
  }
}

Project Structure

my-components/
├── src/
│   ├── components/
│   │   ├── my-button.ts
│   │   └── my-card.ts
│   └── catalogue.ts
├── dist/
├── index.html
└── package.json

Advanced Features

Custom Property Handlers

For complex property types, implement custom logic in your demo:

public static demo = () => html`
  <dees-demowrapper .runAfterRender=${(wrapper) => {
    // Use querySelector to target specific elements
    const component = wrapper.querySelector('my-component');
    if (component) {
      component.addEventListener('property-change', (e) => {
        console.log('Property changed:', e.detail);
      });
    }
    
    // Or handle all elements of a type
    wrapper.querySelectorAll('my-component').forEach(el => {
      el.addEventListener('click', () => console.log('Clicked!'));
    });
  }}>
    <my-component></my-component>
  </dees-demowrapper>
`;

Responsive Testing Helpers

import * as domtools from '@design.estate/dees-domtools';

public static styles = [
  // Media query helpers
  domtools.breakpoints.cssForPhone(css`
    :host { font-size: 14px; }
  `),
  
  domtools.breakpoints.cssForTablet(css`
    :host { font-size: 16px; }
  `),
  
  domtools.breakpoints.cssForDesktop(css`
    :host { font-size: 18px; }
  `)
];

API Reference

setupWccTools(elements, pages?)

Initialize the WCC Tools dashboard.

  • elements: Object mapping element names to element classes
  • pages: Optional object mapping page names to template functions

DeesDemoWrapper

Component for wrapping demos with post-render logic.

  • runAfterRender: Function called after the wrapped elements render
  • Receives the wrapper element itself, providing full DOM API access
  • Use wrapper.querySelector() and wrapper.querySelectorAll() for element selection
  • Access children via wrapper.children property
  • Supports async operations

Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Mobile browsers with Web Components support

This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the license file within this repository.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.

Company Information

Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany

For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

Description
build web component catalogs with viewport preview, property manipulation and precomposed views
Readme 1.2 MiB
Languages
TypeScript 98.3%
HTML 1.7%