blob: c187fbd56d0054b6fbcd2f5bfdbba5bc8b984064 [file] [log] [blame]
bankseand5c849d2025-06-26 15:48:31 +00001/**
2 * Demo module for sketch-view-mode-select component
3 */
4
5import { DemoModule } from "./demo-framework/types";
6import {
7 demoUtils,
8 sampleViewModeConfigs,
9 viewModeScenarios,
10 applyViewModeConfig,
11 createViewModeTestButtons,
12} from "./demo-fixtures/index";
13
14const demo: DemoModule = {
15 title: "View Mode Select Demo",
16 description:
17 "Interactive tab navigation for switching between chat, diff, and terminal views",
18 imports: ["../sketch-view-mode-select"],
19 styles: ["/dist/tailwind.css"],
20
21 setup: async (container: HTMLElement) => {
22 // Create demo sections
23 const basicSection = demoUtils.createDemoSection(
24 "Basic View Mode Selector",
25 "Click buttons to switch between different views",
26 );
27
28 const scenariosSection = demoUtils.createDemoSection(
29 "Different Scenarios",
30 "Pre-configured scenarios showing various diff stats and active modes",
31 );
32
33 const interactiveSection = demoUtils.createDemoSection(
34 "Interactive Testing",
35 "Test different configurations and watch the component update",
36 );
37
38 // Basic view mode selector
39 const basicContainer = document.createElement("div");
40 basicContainer.className = "@container";
41
42 const basicSelector = document.createElement(
43 "sketch-view-mode-select",
44 ) as any;
45 basicSelector.id = "basic-selector";
46 applyViewModeConfig(basicSelector, sampleViewModeConfigs.basic);
47
48 basicContainer.appendChild(basicSelector);
49
50 // Status display for basic selector
51 const basicStatus = document.createElement("div");
52 basicStatus.id = "basic-status";
53 basicStatus.style.cssText = `
54 margin-top: 15px;
55 padding: 10px;
56 background: #f6f8fa;
57 border-radius: 6px;
58 font-family: monospace;
59 font-size: 14px;
60 `;
61
62 const updateBasicStatus = () => {
63 basicStatus.innerHTML = `
64 <strong>Current State:</strong><br>
65 Active Mode: <code>${basicSelector.activeMode}</code><br>
66 Diff Stats: <code>+${basicSelector.diffLinesAdded} -${basicSelector.diffLinesRemoved}</code>
67 `;
68 };
69 updateBasicStatus();
70
71 // Listen for view mode changes
72 basicSelector.addEventListener("view-mode-select", (event: CustomEvent) => {
73 console.log("View mode changed:", event.detail);
74 basicSelector.activeMode = event.detail.mode;
75 updateBasicStatus();
76 });
77
78 // Create scenario examples
79 const scenarioContainer = document.createElement("div");
80 scenarioContainer.style.cssText = `
81 display: grid;
82 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
83 gap: 15px;
84 margin-top: 15px;
85 `;
86
87 viewModeScenarios.forEach((scenario) => {
88 const scenarioCard = document.createElement("div");
89 scenarioCard.style.cssText = `
90 padding: 15px;
91 border: 1px solid #d0d7de;
92 border-radius: 8px;
93 background: white;
94 `;
95
96 const scenarioTitle = document.createElement("h4");
97 scenarioTitle.textContent = scenario.name;
98 scenarioTitle.style.cssText = "margin: 0 0 5px 0; color: #24292f;";
99
100 const scenarioDesc = document.createElement("p");
101 scenarioDesc.textContent = scenario.description;
102 scenarioDesc.style.cssText =
103 "margin: 0 0 10px 0; color: #656d76; font-size: 14px;";
104
105 const scenarioWrapper = document.createElement("div");
106 scenarioWrapper.className = "@container";
107
108 const scenarioSelector = document.createElement(
109 "sketch-view-mode-select",
110 ) as any;
111 applyViewModeConfig(scenarioSelector, scenario.config);
112
113 scenarioWrapper.appendChild(scenarioSelector);
114
115 scenarioCard.appendChild(scenarioTitle);
116 scenarioCard.appendChild(scenarioDesc);
117 scenarioCard.appendChild(scenarioWrapper);
118 scenarioContainer.appendChild(scenarioCard);
119 });
120
121 // Interactive testing component
122 const interactiveSelectorContainer = document.createElement("div");
123 interactiveSelectorContainer.className = "@container";
124
125 const interactiveSelector = document.createElement(
126 "sketch-view-mode-select",
127 ) as any;
128 interactiveSelector.id = "interactive-selector";
129 applyViewModeConfig(interactiveSelector, sampleViewModeConfigs.basic);
130
131 interactiveSelectorContainer.appendChild(interactiveSelector);
132
133 // Status display for interactive selector
134 const interactiveStatus = document.createElement("div");
135 interactiveStatus.id = "interactive-status";
136 interactiveStatus.style.cssText = basicStatus.style.cssText;
137
138 const updateInteractiveStatus = () => {
139 interactiveStatus.innerHTML = `
140 <strong>Interactive Component State:</strong><br>
141 Active Mode: <code>${interactiveSelector.activeMode}</code><br>
142 Diff Lines Added: <code>${interactiveSelector.diffLinesAdded}</code><br>
143 Diff Lines Removed: <code>${interactiveSelector.diffLinesRemoved}</code><br>
144 <em>Click scenario buttons above to test different configurations</em>
145 `;
146 };
147 updateInteractiveStatus();
148
149 // Listen for view mode changes on interactive selector
150 interactiveSelector.addEventListener(
151 "view-mode-select",
152 (event: CustomEvent) => {
153 console.log("Interactive view mode changed:", event.detail);
154 interactiveSelector.activeMode = event.detail.mode;
155 updateInteractiveStatus();
156 },
157 );
158
159 // Custom controls for interactive testing
160 const customControls = document.createElement("div");
161 customControls.style.cssText = `
162 margin: 15px 0;
163 padding: 15px;
164 background: #f6f8fa;
165 border-radius: 6px;
166 `;
167
168 const addLinesButton = demoUtils.createButton("Add +5 Lines", () => {
169 interactiveSelector.diffLinesAdded += 5;
170 interactiveSelector.requestUpdate();
171 updateInteractiveStatus();
172 });
173
174 const removeLinesButton = demoUtils.createButton("Add -3 Lines", () => {
175 interactiveSelector.diffLinesRemoved += 3;
176 interactiveSelector.requestUpdate();
177 updateInteractiveStatus();
178 });
179
180 const clearDiffButton = demoUtils.createButton("Clear Diff", () => {
181 interactiveSelector.diffLinesAdded = 0;
182 interactiveSelector.diffLinesRemoved = 0;
183 interactiveSelector.requestUpdate();
184 updateInteractiveStatus();
185 });
186
187 const randomDiffButton = demoUtils.createButton("Random Diff", () => {
188 interactiveSelector.diffLinesAdded = Math.floor(Math.random() * 100) + 1;
189 interactiveSelector.diffLinesRemoved = Math.floor(Math.random() * 50) + 1;
190 interactiveSelector.requestUpdate();
191 updateInteractiveStatus();
192 });
193
194 customControls.appendChild(addLinesButton);
195 customControls.appendChild(removeLinesButton);
196 customControls.appendChild(clearDiffButton);
197 customControls.appendChild(randomDiffButton);
198
199 // Assemble the demo
200 basicSection.appendChild(basicContainer);
201 basicSection.appendChild(basicStatus);
202
203 scenariosSection.appendChild(scenarioContainer);
204
205 interactiveSection.appendChild(interactiveSelectorContainer);
206
207 // Add test buttons for interactive section
208 createViewModeTestButtons(interactiveSelector, interactiveSection);
209
210 interactiveSection.appendChild(customControls);
211 interactiveSection.appendChild(interactiveStatus);
212
213 container.appendChild(basicSection);
214 container.appendChild(scenariosSection);
215 container.appendChild(interactiveSection);
216
217 // Add container queries responsive testing section
218 const responsiveSection = demoUtils.createDemoSection(
219 "Container Query Responsive Testing",
220 "Demonstrates how the component behaves at different container sizes using Tailwind container queries",
221 );
222
223 // Create explanation text
224 const explanation = document.createElement("p");
225 explanation.style.cssText = "margin: 10px 0; color: #666; font-size: 14px;";
226 explanation.innerHTML = `
227 <strong>Container Queries:</strong> The component now uses Tailwind <code>@container</code> queries instead of viewport media queries.<br>
228 This allows different sized containers to show different responsive behaviors simultaneously.
229 `;
230 responsiveSection.appendChild(explanation);
231
232 // Create different sized container examples
233 const containerExamples = [
234 {
235 title: "Extra Wide Container (700px)",
236 description: "Shows full text labels and complete layout",
237 width: "700px",
238 config: sampleViewModeConfigs.largeDiff,
239 containerClass: "w-[700px]",
240 borderColor: "border-green-500",
241 },
242 {
243 title: "Very Narrow Container (250px)",
244 description: "Shows icons only (text hidden due to container query)",
245 width: "250px",
246 config: sampleViewModeConfigs.terminalActive,
247 containerClass: "w-[250px]",
248 borderColor: "border-orange-500",
249 },
250 ];
251
252 const examplesContainer = document.createElement("div");
253 examplesContainer.style.cssText =
254 "display: flex; flex-direction: column; gap: 20px; margin: 20px 0;";
255
256 containerExamples.forEach((example, index) => {
257 // Create container wrapper
258 const wrapper = document.createElement("div");
259 wrapper.style.cssText = `
260 border: 2px solid;
261 border-radius: 8px;
262 padding: 15px;
263 background: #f9f9f9;
264 `;
265 wrapper.className = example.borderColor;
266
267 // Create title and description
268 const header = document.createElement("div");
269 header.style.cssText = "margin-bottom: 10px;";
270 header.innerHTML = `
271 <h4 style="margin: 0 0 5px 0; font-weight: 600; color: #333;">${example.title}</h4>
272 <p style="margin: 0; font-size: 14px; color: #666;">${example.description}</p>
273 `;
274 wrapper.appendChild(header);
275
276 // Create constrained container for the component
277 const componentContainer = document.createElement("div");
278 componentContainer.className = "@container";
279 componentContainer.style.cssText = `
280 width: ${example.width};
281 border: 1px dashed #ccc;
282 padding: 10px;
283 background: white;
284 border-radius: 4px;
285 `;
286
287 // Create the component
288 const component = document.createElement(
289 "sketch-view-mode-select",
290 ) as any;
291 applyViewModeConfig(component, example.config);
292
293 componentContainer.appendChild(component);
294 wrapper.appendChild(componentContainer);
295 examplesContainer.appendChild(wrapper);
296 });
297
298 responsiveSection.appendChild(examplesContainer);
299
300 // Add interactive container size testing
301 const containerTestSection = document.createElement("div");
302 containerTestSection.style.cssText =
303 "margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd;";
304
305 const interactiveTitle = document.createElement("h4");
306 interactiveTitle.textContent = "Interactive Container Size Testing";
307 interactiveTitle.style.cssText = "margin: 0 0 10px 0; font-weight: 600;";
308
309 const interactiveDesc = document.createElement("p");
310 interactiveDesc.textContent =
311 "Use the buttons below to change the container size and see the responsive behavior in real-time.";
312 interactiveDesc.style.cssText =
313 "margin: 0 0 15px 0; color: #666; font-size: 14px;";
314
315 // Create interactive container
316 const interactiveContainer = document.createElement("div");
317 interactiveContainer.className = "@container";
318 interactiveContainer.style.cssText = `
319 border: 2px solid #007acc;
320 border-radius: 8px;
321 padding: 15px;
322 background: #f0f8ff;
323 transition: width 0.3s ease;
324 width: 700px;
325 `;
326
327 // Create interactive component
328 const interactiveComponent = document.createElement(
329 "sketch-view-mode-select",
330 ) as any;
331 applyViewModeConfig(interactiveComponent, sampleViewModeConfigs.largeDiff);
332
333 // Size info display
334 const sizeInfo = document.createElement("div");
335 sizeInfo.style.cssText =
336 "margin-bottom: 10px; font-family: monospace; font-size: 12px; color: #333;";
337 sizeInfo.textContent = "Current container width: 700px";
338
339 interactiveContainer.appendChild(sizeInfo);
340 interactiveContainer.appendChild(interactiveComponent);
341
342 // Control buttons
343 const controlButtons = document.createElement("div");
344 controlButtons.style.cssText =
345 "margin-top: 15px; display: flex; gap: 8px; flex-wrap: wrap;";
346
347 const sizes = [
348 { label: "Extra Wide (700px)", width: "700px" },
349 { label: "Medium (400px)", width: "400px" },
350 { label: "Very Narrow (250px)", width: "250px" },
351 ];
352
353 sizes.forEach((size) => {
354 const button = demoUtils.createButton(size.label, () => {
355 interactiveContainer.style.width = size.width;
356 sizeInfo.textContent = `Current container width: ${size.width}`;
357 });
358 controlButtons.appendChild(button);
359 });
360
361 containerTestSection.appendChild(interactiveTitle);
362 containerTestSection.appendChild(interactiveDesc);
363 containerTestSection.appendChild(interactiveContainer);
364 containerTestSection.appendChild(controlButtons);
365
366 responsiveSection.appendChild(containerTestSection);
367 container.appendChild(responsiveSection);
368 },
369
370 cleanup: async () => {
371 // Clean up any event listeners or intervals if needed
372 console.log("Cleaning up sketch-view-mode-select demo");
373 },
374};
375
376export default demo;