blob: 660f19a19192a8f48890c6bbfce3f357a3bf801e [file] [log] [blame] [view]
banksean333aa672025-07-13 19:49:21 +00001# Modern Component Architecture: SketchTailwindElement
2
3**IMPORTANT: New component architecture standards for all Sketch web components**
4
5## New Component Standard (Use This)
6
7All new Sketch web components should:
8
91. **Inherit from `SketchTailwindElement`** instead of `LitElement`
102. **Use Tailwind CSS classes** for styling instead of CSS-in-JS
113. **Use property-based composition** instead of slot-based composition
124. **Avoid Shadow DOM** whenever possible
13
14### Example of Modern Component:
15
16```typescript
17import { html } from "lit";
18import { customElement, property } from "lit/decorators.js";
19import { SketchTailwindElement } from "./sketch-tailwind-element";
20import "./sketch-tool-card-base";
21
22@customElement("sketch-tool-card-example")
23export class SketchToolCardExample extends SketchTailwindElement {
24 @property() toolCall: ToolCall;
25 @property() open: boolean;
26
27 render() {
28 const summaryContent = html`<span class="font-mono text-sm text-gray-700">
29 ${this.toolCall?.name}
30 </span>`;
31
32 const inputContent = html`<div class="p-2 bg-gray-100 rounded">
33 <pre class="whitespace-pre-wrap break-words">${this.toolCall?.input}</pre>
34 </div>`;
35
36 return html`<sketch-tool-card-base
37 .open=${this.open}
38 .toolCall=${this.toolCall}
39 .summaryContent=${summaryContent}
40 .inputContent=${inputContent}
41 ></sketch-tool-card-base>`;
42 }
43}
44```
45
46### Key Differences from Legacy Components:
47
48- **Extends SketchTailwindElement** (not LitElement)
49- **Uses sketch-tool-card-base** with property binding (not slots)
50- **Tailwind classes** like `font-mono text-sm text-gray-700` (not CSS-in-JS)
51- **No static styles** or Shadow DOM
52- **Property-based composition** (`.summaryContent=${html\`...\`}`)
53
bankseanc5c3bea2025-07-17 10:11:35 -070054## Preview, debug and iterate on your component changes with the demo server
55
56### Setup (first time):
57
581. Navigate to the webui directory: `cd ./sketch/webui`
592. Install dependencies: `npm install`
603. If you encounter rollup/architecture errors, remove dependencies and reinstall:
61 ```bash
62 rm -rf node_modules package-lock.json
63 npm install
64 ```
65
66### Running the demo server:
67
68- Use the `npm run demo:runner` command to start the demo server. It will render your component changes, populated with fake example data.
69- The server runs at http://localhost:5173/src/web-components/demo/demo-runner.html
70- If you need to write or update the demo definition for an element, do so in demo files like ./demo/some-component-name.demo.ts
71- If you need to add new example data objects for demoing components, do so in ./demo/fixtures
72
banksean333aa672025-07-13 19:49:21 +000073## Legacy Components (Do NOT Use as Examples)
74
75Some existing components still use the old architecture and will be migrated:
76
77- Components that extend `LitElement` directly
78- Components that use `static styles = css\`...\``
79- Components that use slot-based composition (`<slot name="summary"></slot>`)
80- Components that rely on Shadow DOM
81
82**Do not use these legacy patterns for new components.** They are being phased out.
83
Philip Zeyliger33219392025-05-14 20:43:24 -070084# API URLs Must Be Relative
85
86When making fetch requests to backend APIs in Sketch, all URLs **must be relative** without leading slashes. The base URL for Sketch varies depending on how it is deployed and run:
87
88```javascript
89// CORRECT - use relative paths without leading slash
90const response = await fetch(`git/rawdiff?commit=${commit}`);
91const data = await fetch(`git/show?hash=${hash}`);
92
93// INCORRECT - do not use absolute paths with leading slash
94const response = await fetch(`/git/rawdiff?commit=${commit}`); // WRONG!
95const data = await fetch(`/git/show?hash=${hash}`); // WRONG!
96```
97
98The reason for this requirement is that Sketch may be deployed:
99
1001. At the root path of a domain
1012. In a subdirectory
1023. Behind a proxy with a path prefix
1034. In different environments (dev, production)
104
105Using relative paths ensures that requests are correctly routed regardless of the deployment configuration. The browser will resolve the URLs relative to the current page location.