Compare commits

...

5 Commits

Author SHA1 Message Date
578f87a8f9 1.0.94
Some checks failed
Default (tags) / security (push) Failing after 46s
Default (tags) / test (push) Failing after 40s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-06-16 14:36:44 +00:00
0acf341071 1.0.93
Some checks failed
Default (tags) / security (push) Failing after 48s
Default (tags) / test (push) Failing after 40s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-06-16 14:35:32 +00:00
87bbf0bbdc fix(demotools): update DeesDemoWrapper to handle multiple slotted elements in runAfterRender callback 2025-06-16 14:35:28 +00:00
bed41da573 1.0.92
Some checks failed
Default (tags) / security (push) Failing after 50s
Default (tags) / test (push) Failing after 35s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-06-16 14:24:07 +00:00
48f77e7ba2 docs(readme): update documentation with comprehensive overview, quick start guide, and detailed feature descriptions 2025-06-16 14:24:02 +00:00
5 changed files with 380 additions and 86 deletions

View File

@ -1,11 +1,11 @@
{ {
"name": "@design.estate/dees-wcctools", "name": "@design.estate/dees-wcctools",
"version": "1.0.91", "version": "1.0.94",
"private": false, "private": false,
"description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.", "description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.",
"exports": { "exports": {
".": "./dist_ts_web/index.js", ".": "./dist_ts_web/index.js",
"./demoTools": "./dist_ts_demotools" "./demotools": "./dist_ts_demotools"
}, },
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -30,22 +30,30 @@ A utility component for wrapping demo elements with post-render functionality.
**Usage:** **Usage:**
```typescript ```typescript
import { DeesDemoWrapper } from '@design.estate/dees-wcctools/demoTools'; import * as demoTools from '@design.estate/dees-wcctools/demotools';
// In your demo function: // In your demo function:
demo: () => html` demo: () => html`
<dees-demowrapper .runAfterRender=${(element) => { <dees-demowrapper .runAfterRender=${(children: HTMLCollection) => {
// Do something with the rendered element // Access all slotted elements
element.setAttribute('data-demo', 'true'); const firstElement = children[0] as HTMLElement;
console.log('Element rendered:', element); firstElement.setAttribute('data-demo', 'true');
console.log('All slotted elements:', children);
// Work with multiple elements
Array.from(children).forEach(child => {
console.log('Element rendered:', child);
});
}}> }}>
<my-custom-element></my-custom-element> <my-custom-element></my-custom-element>
<div>Additional content</div>
</dees-demowrapper> </dees-demowrapper>
` `
``` ```
**Features:** **Features:**
- Wraps demo elements without affecting layout (uses `display: contents`) - Wraps demo elements without affecting layout (uses `display: contents`)
- Provides access to the rendered element instance after mounting - Provides access to ALL slotted elements via HTMLCollection after mounting
- Supports async operations in runAfterRender callback - Supports async operations in runAfterRender callback
- Automatically handles timing to ensure element is fully rendered - Automatically handles timing to ensure elements are fully rendered
- Can handle multiple slotted elements, not just the first one

429
readme.md
View File

@ -1,101 +1,368 @@
# @design.estate/dees-wcctools # @design.estate/dees-wcctools
wcc tools for creating element catalogues Web Component Development Tools - A powerful framework for building, testing, and documenting web components
## Install ## Overview
To install `@design.estate/dees-wcctools`, you can use npm: `@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
```bash ```bash
npm install @design.estate/dees-wcctools --save # Using npm
npm install @design.estate/dees-wcctools --save-dev
# Using pnpm (recommended)
pnpm add -D @design.estate/dees-wcctools
``` ```
## Usage ## Quick Start
The `@design.estate/dees-wcctools` package provides a set of tools for creating element catalogues using Web Components. It leverages LitElement for creating custom elements and provides a structured way to showcase and test these elements in various environments and themes.
### Setting Up ### 1. Create Your Component
First, ensure that your project is set up to use TypeScript and ESM syntax. This guide assumes you have a basic understanding of TypeScript and modern JavaScript development practices.
Start by importing the necessary tools from `@design.estate/dees-wcctools` in your main TypeScript file.
```typescript ```typescript
import { setupWccTools } from '@design.estate/dees-wcctools'; import { DeesElement, customElement, html, css, property } from '@design.estate/dees-element';
```
### Defining Custom Elements @customElement('my-button')
Define your custom elements using LitElement. Here's a simple example of an element: export class MyButton extends DeesElement {
// Define a demo for the catalogue
public static demo = () => html`
<my-button .label=${'Click me!'} .variant=${'primary'}></my-button>
`;
```typescript
import { LitElement, html, customElement } from 'lit';
@customElement('my-element')
class MyElement extends LitElement {
render() {
return html`<p>Hello, world!</p>`;
}
}
```
### Bootstrapping the WCCTools Dashboard
To showcase your elements, `@design.estate/dees-wcctools` provides a handy way to bootstrap a dashboard where your elements can be registered and displayed.
Create a bootstrap function in your main file or a separate module:
```typescript
async function bootstrapWCCTools() {
// Define your elements here
const elements = {
'my-element': MyElement, // Assuming MyElement is imported
};
// Optionally, define pages as functions returning Lit HTML Templates
const pages = {
home: () => html`<h1>Welcome to My Element Catalogue</h1>`,
};
// Setup the WCCTools dashboard
setupWccTools(elements, pages);
}
```
Call this function to initialize your catalogue:
```typescript
bootstrapWCCTools();
```
### Configurations and Customizations
The `setupWccTools` function accepts two arguments: `elements` and `pages`.
- `elements`: An object where keys are element tags (e.g., 'my-element') and values are the corresponding class definitions.
- `pages`: An optional object where keys are page identifiers and values are functions returning Lit HTML templates.
### Testing Elements
Once the dashboard is set up, navigate to your project in a web browser. You'll see a sidebar listing all registered elements and pages. Clicking on an element name will display it in the main view, allowing you to interact with it and see it in action.
### Theme and Environment Testing
The dashboard also provides options for testing your elements in different environments (e.g., desktop, tablet) and themes (light or dark). This helps ensure that your elements are versatile and adaptable to varying conditions.
### Expanding Your Catalogue
To add more elements to your catalogue, simply extend the `elements` object and rerun `bootstrapWCCTools()`. This modular approach makes it easy to maintain and expand your element catalogue.
### Leveraging TypeScript
Using TypeScript allows you to enforce typing and build more reliable web components. Define properties with decorators, and use TypeScript's features to enhance your component development process.
```typescript
import { LitElement, property, html, customElement } from 'lit';
@customElement('typed-element')
class TypedElement extends LitElement {
@property({ type: String }) @property({ type: String })
name: string = 'World'; public label: string = 'Button';
render() { @property({ type: String })
return html`<p>Hello, ${this.name}!</p>`; 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>
`;
} }
} }
``` ```
### Conclusion ### 2. Set Up Your Catalogue
`@design.estate/dees-wcctools` provides a powerful, flexible platform for developing, showcasing, and testing web components. By leveraging modern development practices like TypeScript and LitElement, you can build a robust catalogue of reusable web components ready for any project.
```typescript
// 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
```html
<!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:
```typescript
public render() {
return html`
<div class="${this.goBright ? 'light-theme' : 'dark-theme'}">
<!-- Your component content -->
</div>
`;
}
```
Or use CSS custom properties:
```typescript
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:
```typescript
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 (children: HTMLCollection) => {
// Access all slotted elements
console.log('Slotted elements:', children.length);
// Access specific element (e.g., first child)
const myComponent = children[0] as MyComponent;
console.log('Component mounted:', myComponent);
// Simulate user interactions
myComponent.value = 'Test value';
await myComponent.updateComplete;
// Trigger methods
myComponent.handleClick();
// Work with multiple elements if present
Array.from(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:
```typescript
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
```typescript
@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
```json
{
"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:
```typescript
public static demo = () => html`
<dees-demowrapper .runAfterRender=${(children) => {
// Set up complex property handling for all children
Array.from(children).forEach(child => {
child.addEventListener('property-change', (e) => {
console.log('Property changed:', e.detail);
});
});
}}>
<my-component></my-component>
</dees-demowrapper>
`;
```
### Responsive Testing Helpers
```typescript
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 complete HTMLCollection of all slotted elements
- Supports async operations
- Access individual elements via array index or Array.from()
## Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers with Web Components support
## License and Legal Information ## License and Legal Information

View File

@ -34,8 +34,29 @@ The properties panel has timing issues detecting rendered elements because:
## Created DeesDemoWrapper Component ## Created DeesDemoWrapper Component
- Location: ts_demotools/demotools.ts - Location: ts_demotools/demotools.ts
- Allows wrapping demo elements with post-render functionality - Allows wrapping demo elements with post-render functionality
- Provides runAfterRender callback that receives the rendered element - Provides runAfterRender callback that receives ALL slotted elements as HTMLCollection
- Uses display: contents to not affect layout - Uses display: contents to not affect layout
- Handles timing automatically with 50ms delay after firstUpdated - Handles timing automatically with 50ms delay after firstUpdated
- Supports both sync and async callbacks - Supports both sync and async callbacks
- Exports available at @design.estate/dees-wcctools/demoTools - Exports available at @design.estate/dees-wcctools/demotools (lowercase)
# Documentation Update (COMPLETED)
## Updated readme.md with:
- Comprehensive overview with feature highlights
- Quick start guide with code examples
- Detailed feature documentation
- Advanced demo tools usage
- Best practices and guidelines
- API reference
- Browser support information
- Complete examples for all major features
# Enhanced DemoWrapper (COMPLETED)
## Modified runAfterRender callback:
- Now receives HTMLCollection of ALL slotted elements instead of just the first one
- Allows access to complete slotted DOM structure
- Updated documentation with correct import path (lowercase 'demotools')
- Examples show how to work with multiple slotted elements
- Maintains backward compatibility by accessing elements via index

View File

@ -3,7 +3,7 @@ import { DeesElement, customElement, html, css, property, type TemplateResult }
@customElement('dees-demowrapper') @customElement('dees-demowrapper')
export class DeesDemoWrapper extends DeesElement { export class DeesDemoWrapper extends DeesElement {
@property({ attribute: false }) @property({ attribute: false })
public runAfterRender: (element: HTMLElement) => void | Promise<void>; public runAfterRender: (children: HTMLCollection) => void | Promise<void>;
public static styles = [ public static styles = [
css` css`
@ -25,14 +25,12 @@ export class DeesDemoWrapper extends DeesElement {
// Wait a bit for slotted content to render // Wait a bit for slotted content to render
await new Promise(resolve => setTimeout(resolve, 50)); await new Promise(resolve => setTimeout(resolve, 50));
// Find the first element child (excluding text nodes) // Get all slotted elements
const slottedElements = this.children; const slottedElements = this.children;
if (slottedElements.length > 0 && this.runAfterRender) { if (slottedElements.length > 0 && this.runAfterRender) {
const firstElement = slottedElements[0] as HTMLElement; // Call the runAfterRender function with all slotted elements
// Call the runAfterRender function with the element
try { try {
await this.runAfterRender(firstElement); await this.runAfterRender(slottedElements);
} catch (error) { } catch (error) {
console.error('Error in runAfterRender:', error); console.error('Error in runAfterRender:', error);
} }