blob: b5d87d29e69ad5df0a624bf9dd6fb16e011dcd06 [file] [log] [blame] [view]
Sean McCullough618bfb22025-06-25 20:52:30 +00001# Sketch Web Components Demo System
Sean McCullough86b56862025-04-18 13:04:03 -07002
Sean McCullough618bfb22025-06-25 20:52:30 +00003This directory contains an automated demo system for Sketch web components that reduces maintenance overhead and provides a consistent development experience.
Sean McCullough86b56862025-04-18 13:04:03 -07004
Sean McCullough618bfb22025-06-25 20:52:30 +00005## Overview
6
7The demo system consists of:
8
9- **TypeScript Demo Modules** (`*.demo.ts`) - Component-specific demo configurations
10- **Demo Framework** (`demo-framework/`) - Shared infrastructure for loading and running demos
11- **Shared Fixtures** (`demo-fixtures/`) - Common fake data and utilities
banksean581bd792025-07-20 18:30:12 -070012- **Demo Runner** (`demo.html`) - Interactive demo browser
Sean McCullough618bfb22025-06-25 20:52:30 +000013- **Auto-generated Index** - Automatically maintained list of available demos
14
15## Quick Start
16
17### Running Demos
18
19```bash
20# Start the demo server
21npm run demo
22
23# Visit the demo runner
banksean581bd792025-07-20 18:30:12 -070024open http://localhost:5173/src/web-components/demo/demo.html
Sean McCullough618bfb22025-06-25 20:52:30 +000025
26# Or view the auto-generated index
27open http://localhost:5173/src/web-components/demo/index-generated.html
28```
29
30### Creating a New Demo
31
321. Create a new demo module file: `your-component.demo.ts`
33
34```typescript
35import { DemoModule } from "./demo-framework/types";
36import { demoUtils, sampleData } from "./demo-fixtures/index";
37
38const demo: DemoModule = {
39 title: "Your Component Demo",
40 description: "Interactive demo showing component functionality",
41 imports: ["your-component.ts"], // Component files to import
42
43 setup: async (container: HTMLElement) => {
44 // Create demo sections
45 const section = demoUtils.createDemoSection(
46 "Basic Usage",
47 "Description of what this demo shows",
48 );
49
50 // Create your component
51 const component = document.createElement("your-component") as any;
52 component.data = sampleData.yourData;
53
54 // Add to container
55 section.appendChild(component);
56 container.appendChild(section);
57 },
58
59 cleanup: async () => {
60 // Optional cleanup when demo is unloaded
61 },
62};
63
64export default demo;
65```
66
672. Regenerate the index:
68
69```bash
70cd src/web-components/demo
71npx tsx generate-index.ts
72```
73
743. Your demo will automatically appear in the demo runner!
75
76## Demo Module Structure
77
78### Required Properties
79
80- `title`: Display name for the demo
81- `imports`: Array of component files to import (relative to parent directory)
82- `setup`: Function that creates the demo content
83
84### Optional Properties
85
86- `description`: Brief description of what the demo shows
87- `styles`: Additional CSS files to load
88- `customStyles`: Inline CSS styles
89- `cleanup`: Function called when demo is unloaded
90
91### Setup Function
92
93The setup function receives a container element and should populate it with demo content:
94
95```typescript
96setup: async (container: HTMLElement) => {
97 // Use demo utilities for consistent styling
98 const section = demoUtils.createDemoSection("Title", "Description");
99
100 // Create and configure your component
101 const component = document.createElement("my-component");
102 component.setAttribute("data", JSON.stringify(sampleData));
103
104 // Add interactive controls
105 const button = demoUtils.createButton("Reset", () => {
106 component.reset();
107 });
108
109 // Assemble the demo
110 section.appendChild(component);
111 section.appendChild(button);
112 container.appendChild(section);
113};
114```
115
116## Shared Fixtures
117
118The `demo-fixtures/` directory contains reusable fake data and utilities:
119
120```typescript
121import {
122 sampleToolCalls,
123 sampleTimelineMessages,
124 sampleContainerState,
125 demoUtils,
126} from "./demo-fixtures/index";
127```
128
129### Available Fixtures
130
131- `sampleToolCalls` - Various tool call examples
132- `sampleTimelineMessages` - Chat/timeline message data
133- `sampleContainerState` - Container status information
134- `demoUtils` - Helper functions for creating demo UI elements
135
136### Demo Utilities
137
138- `demoUtils.createDemoSection(title, description)` - Create a styled demo section
139- `demoUtils.createButton(text, onClick)` - Create a styled button
140- `demoUtils.delay(ms)` - Promise-based delay function
141
142## Benefits of This System
143
144### For Developers
145
146- **TypeScript Support**: Full type checking for demo code and shared data
147- **Hot Module Replacement**: Instant updates when demo code changes
148- **Shared Data**: Consistent fake data across all demos
149- **Reusable Utilities**: Common demo patterns abstracted into utilities
150- **Auto-discovery**: New demos automatically appear in the index
151
152### For Maintenance
153
154- **No Boilerplate**: No need to copy HTML structure between demos
155- **Centralized Styling**: Demo appearance controlled in one place
156- **Automated Index**: Never forget to update the index page
157- **Type Safety**: Catch errors early with TypeScript compilation
158
159## Vite Integration
160
161The system is designed to work seamlessly with Vite:
162
163- **Dynamic Imports**: Demo modules are loaded on demand
164- **TypeScript Compilation**: `.demo.ts` files are compiled automatically
165- **HMR Support**: Changes to demos or fixtures trigger instant reloads
166- **Dependency Tracking**: Vite knows when to reload based on imports
167
168## Migration from HTML Demos
169
170To convert an existing HTML demo:
171
1721. Extract the component setup JavaScript into a `setup` function
1732. Move shared data to `demo-fixtures/`
1743. Replace HTML boilerplate with `demoUtils` calls
1754. Convert inline styles to `customStyles` property
1765. Test with the demo runner
177
178## File Structure
179
180```
181demo/
182├── demo-framework/
183│ ├── types.ts # TypeScript interfaces
banksean581bd792025-07-20 18:30:12 -0700184│ └── demo.ts # Demo loading and execution
Sean McCullough618bfb22025-06-25 20:52:30 +0000185├── demo-fixtures/
186│ ├── tool-calls.ts # Tool call sample data
187│ ├── timeline-messages.ts # Message sample data
188│ ├── container-status.ts # Status sample data
189│ └── index.ts # Centralized exports
190├── generate-index.ts # Index generation script
banksean581bd792025-07-20 18:30:12 -0700191├── demo.html # Interactive demo browser
Sean McCullough618bfb22025-06-25 20:52:30 +0000192├── index-generated.html # Auto-generated index
193├── *.demo.ts # Individual demo modules
194└── readme.md # This file
195```
196
197## Advanced Usage
198
199### Custom Styling
200
201```typescript
202const demo: DemoModule = {
203 // ...
204 customStyles: `
205 .my-demo-container {
206 background: #f0f0f0;
207 padding: 20px;
208 border-radius: 8px;
209 }
210 `,
211 setup: async (container) => {
212 container.className = "my-demo-container";
213 // ...
214 },
215};
216```
217
218### Progressive Loading
219
220```typescript
221setup: async (container) => {
222 const messages = [];
223 const timeline = document.createElement("sketch-timeline");
224
225 // Add messages progressively
226 for (let i = 0; i < sampleMessages.length; i++) {
227 await demoUtils.delay(500);
228 messages.push(sampleMessages[i]);
229 timeline.messages = [...messages];
230 }
231};
232```
233
234### Cleanup
235
236```typescript
237let intervalId: number;
238
239const demo: DemoModule = {
240 // ...
241 setup: async (container) => {
242 // Set up interval for updates
243 intervalId = setInterval(() => {
244 updateComponent();
245 }, 1000);
246 },
247
248 cleanup: async () => {
249 // Clean up interval
250 if (intervalId) {
251 clearInterval(intervalId);
252 }
253 },
254};
255```
256
257For more examples, see the existing demo modules in this directory.