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