/**
* ds-quick-wins-script.js
* Quick Wins analyzer - finds low-effort, high-impact design system improvements
* MVP2: Identifies inconsistencies and suggests standardization opportunities
*/
export default class QuickWinsScript extends HTMLElement {
constructor() {
super();
this.analysisResults = null;
this.isAnalyzing = false;
}
connectedCallback() {
this.render();
this.setupEventListeners();
}
render() {
this.innerHTML = `
Design System Quick Wins
Identify low-effort, high-impact improvements to your design system
⏳
Analyzing design system...
`;
}
setupEventListeners() {
const analyzeBtn = this.querySelector('#analyze-btn');
if (analyzeBtn) {
analyzeBtn.addEventListener('click', () => this.analyzeDesignSystem());
}
}
async analyzeDesignSystem() {
this.isAnalyzing = true;
const loadingContainer = this.querySelector('#loading-container');
const resultsContainer = this.querySelector('#results-container');
loadingContainer.style.display = 'block';
resultsContainer.style.display = 'none';
// Simulate analysis
await new Promise(resolve => setTimeout(resolve, 1500));
this.analysisResults = this.generateAnalysisResults();
this.renderResults();
loadingContainer.style.display = 'none';
resultsContainer.style.display = 'block';
this.isAnalyzing = false;
}
generateAnalysisResults() {
return [
{
title: 'Consolidate Color Palette',
impact: 'high',
effort: 'low',
description: 'Found 23 unique colors in codebase, but only 8 are documented tokens. Consolidate to reduce cognitive load.',
recommendation: 'Extract 15 undocumented colors and add to token library',
estimate: '2 hours',
files_affected: 34
},
{
title: 'Standardize Spacing Scale',
impact: 'high',
effort: 'low',
description: 'Spacing values are inconsistent (4px, 6px, 8px, 12px, 16px, 20px, 24px, 32px). Reduce to 6-8 standard values.',
recommendation: 'Use 4px, 8px, 12px, 16px, 24px, 32px as standard spacing scale',
estimate: '3 hours',
files_affected: 67
},
{
title: 'Create Typography System',
impact: 'high',
effort: 'medium',
description: 'Typography scales vary across components. Establish consistent type hierarchy.',
recommendation: 'Define 5 font sizes (12px, 14px, 16px, 18px, 24px) with line-height ratios',
estimate: '4 hours',
files_affected: 45
},
{
title: 'Document Component Variants',
impact: 'medium',
effort: 'low',
description: 'Button component has 7 undocumented variants in use. Update documentation.',
recommendation: 'Add variant definitions and usage guidelines to Storybook',
estimate: '1 hour',
files_affected: 12
},
{
title: 'Establish Naming Convention',
impact: 'medium',
effort: 'low',
description: 'Token names are inconsistent (color-primary vs primaryColor vs primary-color).',
recommendation: 'Adopt kebab-case convention: color-primary, spacing-sm, font-body',
estimate: '2 hours',
files_affected: 89
},
{
title: 'Create Shadow System',
impact: 'medium',
effort: 'medium',
description: 'Shadow values are hardcoded throughout. Create reusable shadow tokens.',
recommendation: 'Define 3-4 elevation levels: shadow-sm, shadow-md, shadow-lg, shadow-xl',
estimate: '2 hours',
files_affected: 23
}
];
}
renderResults() {
const container = this.querySelector('#results-container');
const results = this.analysisResults;
const highImpact = results.filter(r => r.impact === 'high');
const mediumImpact = results.filter(r => r.impact === 'medium');
const totalFiles = results.reduce((sum, r) => sum + r.files_affected, 0);
// Build stats efficiently
const statsHtml = this.buildStatsCards(results.length, highImpact.length, totalFiles);
// Build cards with memoization
const highImpactHtml = highImpact.map(win => this.renderWinCard(win)).join('');
const mediumImpactHtml = mediumImpact.map(win => this.renderWinCard(win)).join('');
let html = `
${statsHtml}
High Impact Opportunities
${highImpactHtml}
Medium Impact Opportunities
${mediumImpactHtml}
`;
container.innerHTML = html;
}
buildStatsCards(total, highCount, fileCount) {
return `
${total}
Total Opportunities
${fileCount}
Files Affected
`;
}
renderWinCard(win) {
const impactColor = win.impact === 'high' ? '#FF9800' : '#0066CC';
const effortColor = win.effort === 'low' ? '#4CAF50' : win.effort === 'medium' ? '#FF9800' : '#F44336';
return `
${win.title}
${win.impact} impact
${win.effort} effort
${win.description}
Recommendation: ${win.recommendation}
⏱️ ${win.estimate}
📁 ${win.files_affected} files
`;
}
}
customElements.define('ds-quick-wins-script', QuickWinsScript);