summaryrefslogtreecommitdiff
path: root/ui/tailwindcss/.claude/hooks/pre-push
diff options
context:
space:
mode:
Diffstat (limited to 'ui/tailwindcss/.claude/hooks/pre-push')
-rwxr-xr-xui/tailwindcss/.claude/hooks/pre-push353
1 files changed, 353 insertions, 0 deletions
diff --git a/ui/tailwindcss/.claude/hooks/pre-push b/ui/tailwindcss/.claude/hooks/pre-push
new file mode 100755
index 0000000..7520ac6
--- /dev/null
+++ b/ui/tailwindcss/.claude/hooks/pre-push
@@ -0,0 +1,353 @@
+#!/bin/bash
+
+# TailwindCSS Pre-push Hook
+# Final checks before pushing code to ensure production-ready TailwindCSS usage
+
+set -e
+
+echo "🎨 Running TailwindCSS pre-push validation..."
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Function to print colored output
+print_status() {
+ local color=$1
+ local message=$2
+ echo -e "${color}${message}${NC}"
+}
+
+# Production build test
+test_production_build() {
+ print_status $BLUE "Testing production build..."
+
+ # Check if build script exists
+ if npm run --silent 2>/dev/null | grep -q "build"; then
+ print_status $BLUE "Running production build test..."
+
+ # Create a backup of current built files
+ if [[ -d "dist" ]]; then
+ mv dist dist.backup
+ fi
+ if [[ -d "build" ]]; then
+ mv build build.backup
+ fi
+ if [[ -d ".next" ]]; then
+ mv .next .next.backup
+ fi
+
+ # Run build
+ if npm run build >/dev/null 2>&1; then
+ print_status $GREEN "✅ Production build successful"
+
+ # Analyze build output
+ analyze_build_output
+ else
+ print_status $RED "❌ Production build failed"
+
+ # Restore backups
+ restore_backups
+ exit 1
+ fi
+
+ # Restore backups
+ restore_backups
+ else
+ print_status $YELLOW "⚠️ No build script found. Skipping production build test"
+ fi
+}
+
+# Restore backup directories
+restore_backups() {
+ [[ -d "dist.backup" ]] && rm -rf dist && mv dist.backup dist
+ [[ -d "build.backup" ]] && rm -rf build && mv build.backup build
+ [[ -d ".next.backup" ]] && rm -rf .next && mv .next.backup .next
+}
+
+# Analyze build output for CSS optimization
+analyze_build_output() {
+ print_status $BLUE "Analyzing CSS build output..."
+
+ # Find CSS files in build output
+ local css_files=$(find dist build .next 2>/dev/null -name "*.css" -type f | head -5)
+
+ if [[ -n "$css_files" ]]; then
+ local total_size=0
+ local file_count=0
+
+ while IFS= read -r file; do
+ if [[ -f "$file" ]]; then
+ local size=$(wc -c < "$file")
+ local size_kb=$((size / 1024))
+ total_size=$((total_size + size))
+ file_count=$((file_count + 1))
+
+ print_status $BLUE "📄 $(basename "$file"): ${size_kb}KB"
+
+ # Warn about large CSS files
+ if [[ $size_kb -gt 200 ]]; then
+ print_status $YELLOW "⚠️ Large CSS file detected (${size_kb}KB)"
+ print_status $YELLOW " Consider optimizing TailwindCSS configuration"
+ fi
+ fi
+ done <<< "$css_files"
+
+ local total_kb=$((total_size / 1024))
+ print_status $GREEN "📊 Total CSS size: ${total_kb}KB across ${file_count} files"
+
+ # Overall size warning
+ if [[ $total_kb -gt 500 ]]; then
+ print_status $RED "❌ CSS bundle too large (${total_kb}KB > 500KB)"
+ print_status $RED " Optimize before pushing to production"
+ exit 1
+ elif [[ $total_kb -gt 300 ]]; then
+ print_status $YELLOW "⚠️ CSS bundle size is high (${total_kb}KB)"
+ print_status $YELLOW " Consider optimization for better performance"
+ fi
+ else
+ print_status $YELLOW "⚠️ No CSS files found in build output"
+ fi
+}
+
+# Validate CSS purging effectiveness
+validate_purging() {
+ print_status $BLUE "Validating CSS purging effectiveness..."
+
+ # Build CSS for analysis
+ if command -v npx >/dev/null 2>&1 && [[ -f "tailwind.config.js" ]]; then
+ # Create temporary input file
+ echo "@tailwind base; @tailwind components; @tailwind utilities;" > temp-input.css
+
+ # Generate full CSS (no purging)
+ if npx tailwindcss -i temp-input.css -o temp-full.css >/dev/null 2>&1; then
+ local full_size=$(wc -c < temp-full.css)
+
+ # Generate purged CSS (with content)
+ if npx tailwindcss -i temp-input.css -o temp-purged.css --minify >/dev/null 2>&1; then
+ local purged_size=$(wc -c < temp-purged.css)
+ local reduction_percent=$(( (full_size - purged_size) * 100 / full_size ))
+
+ print_status $GREEN "✅ CSS purging reduces bundle by ${reduction_percent}%"
+ print_status $BLUE " Full: $((full_size / 1024))KB → Purged: $((purged_size / 1024))KB"
+
+ # Warn about ineffective purging
+ if [[ $reduction_percent -lt 70 ]]; then
+ print_status $YELLOW "⚠️ Low purging effectiveness (${reduction_percent}%)"
+ print_status $YELLOW " Check content paths in tailwind.config.js"
+ fi
+ fi
+ fi
+
+ # Cleanup temporary files
+ rm -f temp-input.css temp-full.css temp-purged.css
+ fi
+}
+
+# Security and best practices validation
+validate_security() {
+ print_status $BLUE "Validating security and best practices..."
+
+ # Check for hardcoded values that might contain sensitive data
+ local suspicious_patterns=$(grep -r "class[Name]*=.*\(password\|token\|key\|secret\)" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | head -3 || true)
+
+ if [[ -n "$suspicious_patterns" ]]; then
+ print_status $YELLOW "⚠️ Suspicious patterns in class names:"
+ echo "$suspicious_patterns"
+ fi
+
+ # Check for XSS-prone dynamic class generation
+ local dynamic_classes=$(grep -r "class[Name]*=.*\${.*}" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | wc -l)
+
+ if [[ $dynamic_classes -gt 20 ]]; then
+ print_status $YELLOW "⚠️ High usage of dynamic class generation (${dynamic_classes} instances)"
+ print_status $YELLOW " Ensure proper sanitization of user input"
+ fi
+
+ print_status $GREEN "✅ Security validation completed"
+}
+
+# Performance impact analysis
+analyze_performance_impact() {
+ print_status $BLUE "Analyzing performance impact..."
+
+ # Check for performance-impacting patterns
+ local heavy_animations=$(grep -r "animate-\(bounce\|ping\|pulse\|spin\)" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $heavy_animations -gt 20 ]]; then
+ print_status $YELLOW "⚠️ High usage of animations (${heavy_animations} instances)"
+ print_status $YELLOW " Consider performance impact on low-end devices"
+ fi
+
+ # Check for layout-shifting utilities
+ local layout_shifts=$(grep -r "transition-\(width\|height\|padding\|margin\)" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $layout_shifts -gt 10 ]]; then
+ print_status $YELLOW "⚠️ Layout-shifting transitions detected (${layout_shifts} instances)"
+ print_status $YELLOW " May cause poor Cumulative Layout Shift (CLS) scores"
+ fi
+
+ # Check for excessive gradient usage
+ local gradients=$(grep -r "gradient-to-\|from-\|via-\|to-" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $gradients -gt 50 ]]; then
+ print_status $YELLOW "⚠️ Heavy gradient usage (${gradients} instances)"
+ print_status $YELLOW " Consider performance impact and CSS bundle size"
+ fi
+
+ print_status $GREEN "✅ Performance analysis completed"
+}
+
+# Browser compatibility check
+check_browser_compatibility() {
+ print_status $BLUE "Checking browser compatibility..."
+
+ local config_file="tailwind.config.js"
+ if [[ -f "tailwind.config.ts" ]]; then
+ config_file="tailwind.config.ts"
+ fi
+
+ # Check for modern CSS features that might need fallbacks
+ local modern_features=$(grep -r "\(backdrop-\|container\|aspect-\)" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $modern_features -gt 0 ]]; then
+ print_status $YELLOW "⚠️ Modern CSS features detected (${modern_features} instances)"
+ print_status $YELLOW " Verify browser support requirements"
+
+ # Check for autoprefixer
+ if npm list autoprefixer >/dev/null 2>&1; then
+ print_status $GREEN "✅ Autoprefixer installed for vendor prefixes"
+ else
+ print_status $YELLOW "⚠️ Consider installing autoprefixer for better browser support"
+ fi
+ fi
+
+ print_status $GREEN "✅ Browser compatibility check completed"
+}
+
+# Final accessibility audit
+final_accessibility_audit() {
+ print_status $BLUE "Running final accessibility audit..."
+
+ # Check for proper focus management
+ local focus_traps=$(grep -r "focus-trap\|focus-within\|focus-visible" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $focus_traps -eq 0 ]]; then
+ print_status $YELLOW "⚠️ No focus management utilities detected"
+ print_status $YELLOW " Ensure proper keyboard navigation support"
+ else
+ print_status $GREEN "✅ Focus management utilities found"
+ fi
+
+ # Check for color contrast considerations
+ local contrast_utilities=$(grep -r "contrast-\|brightness-" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $contrast_utilities -gt 0 ]]; then
+ print_status $GREEN "✅ Color contrast utilities in use"
+ fi
+
+ # Check for screen reader utilities
+ local sr_utilities=$(grep -r "sr-only\|not-sr-only" src/ --include="*.jsx" --include="*.tsx" --include="*.vue" --include="*.html" 2>/dev/null | wc -l)
+
+ if [[ $sr_utilities -eq 0 ]]; then
+ print_status $YELLOW "⚠️ No screen reader utilities detected"
+ print_status $YELLOW " Consider accessibility for screen reader users"
+ else
+ print_status $GREEN "✅ Screen reader utilities found"
+ fi
+
+ print_status $GREEN "✅ Accessibility audit completed"
+}
+
+# Generate pre-push report
+generate_push_report() {
+ print_status $BLUE "Generating pre-push report..."
+
+ local report_file=".tailwindcss-push-report.txt"
+ local timestamp=$(date)
+
+ cat > "$report_file" << EOF
+TailwindCSS Pre-Push Report
+===========================
+Generated: $timestamp
+Branch: $(git branch --show-current 2>/dev/null || echo "unknown")
+Commit: $(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
+
+Build Status:
+$(npm run build >/dev/null 2>&1 && echo "✅ Build successful" || echo "❌ Build failed")
+
+CSS Bundle Analysis:
+$(find dist build .next 2>/dev/null -name "*.css" -type f | while read file; do
+ if [[ -f "$file" ]]; then
+ echo "- $(basename "$file"): $(($(wc -c < "$file") / 1024))KB"
+ fi
+done | head -5 || echo "- No CSS files found")
+
+Code Quality Checks:
+- Long class strings: $(grep -r "class[Name]*=['\"][^'\"]*['\"]" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | sed -E 's/.*class[Name]*=["'\''`]([^"'\''`]*)["'\''`].*/\1/' | awk 'length($0) > 150' | wc -l | tr -d ' ')
+- Dynamic classes: $(grep -r "class[Name]*=.*\${.*}" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
+- Arbitrary values: $(grep -r "\[\w*\]" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
+
+Performance Metrics:
+- Animation utilities: $(grep -r "animate-" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
+- Layout transitions: $(grep -r "transition-\(width\|height\|padding\|margin\)" src/ 2>/dev/null | wc -l | tr -d ' ')
+- Gradient usage: $(grep -r "gradient-to-\|from-\|via-\|to-" src/ 2>/dev/null | wc -l | tr -d ' ')
+
+Accessibility Features:
+- Focus utilities: $(grep -r "focus-" src/ --include="*.jsx" --include="*.tsx" 2>/dev/null | wc -l | tr -d ' ')
+- Screen reader utilities: $(grep -r "sr-only\|not-sr-only" src/ 2>/dev/null | wc -l | tr -d ' ')
+
+Recommendations:
+$(if grep -r "class[Name]*=['\"][^'\"]*['\"]" src/ 2>/dev/null | sed -E 's/.*class[Name]*=["'\''`]([^"'\''`]*)["'\''`].*/\1/' | awk 'length($0) > 150' | head -1 >/dev/null 2>&1; then echo "- Consider component extraction for long utility combinations"; fi)
+$(if [[ $(grep -r "\[\w*\]" src/ 2>/dev/null | wc -l) -gt 10 ]]; then echo "- Consider adding custom utilities to config instead of arbitrary values"; fi)
+$(if [[ $(grep -r "animate-" src/ 2>/dev/null | wc -l) -gt 20 ]]; then echo "- Review animation usage for performance impact"; fi)
+
+Status: $(if npm run build >/dev/null 2>&1; then echo "✅ Ready for production"; else echo "❌ Issues detected - review before pushing"; fi)
+EOF
+
+ print_status $GREEN "✅ Pre-push report saved to $report_file"
+
+ # Show critical issues in console
+ if ! npm run build >/dev/null 2>&1; then
+ print_status $RED "❌ Build failures detected - see report for details"
+ return 1
+ fi
+
+ return 0
+}
+
+# Main execution
+main() {
+ local start_time=$(date +%s)
+
+ print_status $BLUE "🎨 TailwindCSS Pre-Push Validation"
+ print_status $BLUE "===================================="
+
+ # Run all validation tasks
+ test_production_build
+ validate_purging
+ validate_security
+ analyze_performance_impact
+ check_browser_compatibility
+ final_accessibility_audit
+
+ # Generate final report
+ if generate_push_report; then
+ local end_time=$(date +%s)
+ local duration=$((end_time - start_time))
+
+ print_status $GREEN "✅ All pre-push validations completed in ${duration}s"
+ print_status $BLUE "🚀 Code is ready for production push!"
+ print_status $YELLOW "📄 See .tailwindcss-push-report.txt for detailed analysis"
+ else
+ print_status $RED "❌ Pre-push validation failed"
+ print_status $RED "Fix issues before pushing to production"
+ exit 1
+ fi
+}
+
+# Run the main function
+main \ No newline at end of file