demo-toggles.js

  1// ============================================
  2// DEMO TOGGLES - Handle before/after toggle interactions
  3// ============================================
  4
  5import { getCommandDemo } from './demos/commands/index.js';
  6import { getSkillDemo } from './demos/skills/index.js';
  7
  8/**
  9 * Setup toggle handlers for skill demos
 10 */
 11export function setupDemoToggles() {
 12  document.querySelectorAll('.demo-toggle-switch').forEach(toggle => {
 13    // Skip if already has handler
 14    if (toggle.dataset.initialized) return;
 15    toggle.dataset.initialized = 'true';
 16    
 17    toggle.addEventListener('click', () => {
 18      const demoId = toggle.dataset.demo;
 19      const isActive = toggle.classList.toggle('active');
 20
 21      // Update ARIA state
 22      toggle.setAttribute('aria-checked', isActive ? 'true' : 'false');
 23
 24      // Update labels
 25      const labels = toggle.parentElement.querySelectorAll('.demo-toggle-label');
 26      labels[0].classList.toggle('active', !isActive);
 27      labels[1].classList.toggle('active', isActive);
 28
 29      // Update demo state
 30      handleDemoToggle(demoId, isActive);
 31    });
 32  });
 33  
 34  // Setup interactive buttons
 35  setupInteractiveButtons();
 36}
 37
 38/**
 39 * Setup toggle handlers for command demos
 40 */
 41export function setupCommandDemoToggles(allCommands, selectCommand) {
 42  document.querySelectorAll('.command-demo-area .demo-toggle-switch').forEach(toggle => {
 43    // Skip if already has handler
 44    if (toggle.dataset.initialized) return;
 45    toggle.dataset.initialized = 'true';
 46    
 47    toggle.addEventListener('click', () => {
 48      const demoId = toggle.dataset.demo;
 49      const isActive = toggle.classList.toggle('active');
 50
 51      // Update ARIA state
 52      toggle.setAttribute('aria-checked', isActive ? 'true' : 'false');
 53
 54      const labels = toggle.parentElement.querySelectorAll('.demo-toggle-label');
 55      labels[0].classList.toggle('active', !isActive);
 56      labels[1].classList.toggle('active', isActive);
 57
 58      handleCommandDemoToggle(demoId, isActive);
 59    });
 60  });
 61  
 62  document.querySelectorAll('.command-detail-panel .relationship-tag').forEach(tag => {
 63    tag.addEventListener('click', () => {
 64      const commandId = tag.dataset.command;
 65      const command = allCommands.find(c => c.id === commandId);
 66      if (command) selectCommand(command);
 67    });
 68  });
 69}
 70
 71/**
 72 * Setup interactive demo buttons (like the "like" button)
 73 */
 74function setupInteractiveButtons() {
 75  document.querySelectorAll('.int-fb-active[data-action="like"]').forEach(btn => {
 76    if (btn.dataset.initialized) return;
 77    btn.dataset.initialized = 'true';
 78    
 79    btn.addEventListener('click', () => {
 80      btn.classList.toggle('liked');
 81      const label = btn.nextElementSibling;
 82      if (label) {
 83        label.textContent = btn.classList.contains('liked') ? 'Liked!' : 'Click to try!';
 84      }
 85    });
 86  });
 87}
 88
 89/**
 90 * Handle skill demo toggle
 91 */
 92function handleDemoToggle(demoId, isAfter) {
 93  const viewport = document.getElementById(`${demoId}-viewport`);
 94  if (!viewport) return;
 95  
 96  viewport.dataset.state = isAfter ? 'after' : 'before';
 97  
 98  // Parse skill ID and tab ID from demoId (e.g., "ux-writing-errors")
 99  const parts = demoId.split('-');
100  const tabId = parts.pop();
101  const skillId = parts.join('-');
102  
103  const skill = getSkillDemo(skillId);
104  if (!skill) return;
105  
106  const tab = skill.tabs.find(t => t.id === tabId);
107  if (!tab) return;
108  
109  // Check for custom toggle handler
110  if (tab.onToggle) {
111    tab.onToggle(viewport, isAfter);
112    return;
113  }
114  
115  // Check for CSS class toggle
116  if (tab.beforeClass && tab.afterClass) {
117    const demo = viewport.firstElementChild;
118    if (demo) {
119      demo.className = isAfter ? tab.afterClass : tab.beforeClass;
120    }
121    return;
122  }
123  
124  // HTML swap
125  if (tab.after && tab.before) {
126    viewport.innerHTML = isAfter ? tab.after : tab.before;
127    
128    // Run after-render callback if exists
129    if (isAfter && tab.onAfterRender) {
130      tab.onAfterRender();
131    }
132  }
133}
134
135/**
136 * Handle command demo toggle
137 */
138function handleCommandDemoToggle(demoId, isAfter) {
139  // Extract command ID from demoId (e.g., "command-normalize" -> "normalize")
140  const commandId = demoId.replace('command-', '');
141  const demo = getCommandDemo(commandId);
142  
143  if (!demo) return;
144  
145  const viewport = document.getElementById(`${demoId}-viewport`);
146  if (!viewport) return;
147  
148  viewport.dataset.state = isAfter ? 'after' : 'before';
149  
150  // Check for custom toggle handler
151  if (demo.onToggle) {
152    demo.onToggle(viewport, isAfter);
153    return;
154  }
155  
156  // HTML swap
157  if (demo.after && demo.before) {
158    viewport.innerHTML = isAfter ? demo.after : demo.before;
159  }
160}