### Custom Button System Implementation Created modern button system to replace Bootstrap buttons: - ✅ Created core/_buttons-custom.scss (550+ lines) - ✅ CSS Custom Properties for easy customization - ✅ 8 color variants (primary, secondary, success, danger, warning, info, light, dark) - ✅ Outline and Ghost variants - ✅ 4 sizes (sm, md, lg, xl) - ✅ Special variants (block, icon, circle, link) - ✅ Loading state with spinner animation - ✅ Button groups support - ✅ Modern animations (hover, active, focus) ### Template Migration Migrated 65 HTML templates using automated Python script: - Replaced .btn → .button - Replaced .btn-primary → .button--primary - Replaced .btn-outline-* → .button--outline button--* - Replaced size classes .btn-sm → .button--sm - Total changes: 354 → 347 button usages ### Results - app.css: 137 KB → 148 KB (+11 KB for custom buttons) - Templates changed: 65 files - Remaining .btn classes: 133 (mostly btn-close for modals) - New .button classes: 347 ### Backward Compatibility Kept @extend rules in _buttons-custom.scss for gradual migration. Can be removed after complete migration. Next step: Remove Bootstrap button imports from custom-bootstrap.scss
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Скрипт для миграции Bootstrap кнопок на новую систему
|
|
Заменяет .btn классы на .button классы
|
|
"""
|
|
import re
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# Карта замен Bootstrap классов на новые
|
|
REPLACEMENTS = {
|
|
# Основной класс
|
|
r'\bbtn\b(?!-)': 'button',
|
|
|
|
# Цветовые варианты
|
|
r'\bbtn-primary\b': 'button--primary',
|
|
r'\bbtn-secondary\b': 'button--secondary',
|
|
r'\bbtn-success\b': 'button--success',
|
|
r'\bbtn-danger\b': 'button--danger',
|
|
r'\bbtn-warning\b': 'button--warning',
|
|
r'\bbtn-info\b': 'button--info',
|
|
r'\bbtn-light\b': 'button--light',
|
|
r'\bbtn-dark\b': 'button--dark',
|
|
|
|
# Outline варианты
|
|
r'\bbtn-outline-primary\b': 'button--outline button--primary',
|
|
r'\bbtn-outline-secondary\b': 'button--outline button--secondary',
|
|
r'\bbtn-outline-success\b': 'button--outline button--success',
|
|
r'\bbtn-outline-danger\b': 'button--outline button--danger',
|
|
r'\bbtn-outline-warning\b': 'button--outline button--warning',
|
|
r'\bbtn-outline-info\b': 'button--outline button--info',
|
|
|
|
# Размеры
|
|
r'\bbtn-sm\b': 'button--sm',
|
|
r'\bbtn-lg\b': 'button--lg',
|
|
r'\bbtn-block\b': 'button--block',
|
|
|
|
# Специальные (кастомные классы, которые уже есть)
|
|
r'\bbtn-ghost\b': 'button--ghost',
|
|
r'\bbtn-icon\b': 'button--icon',
|
|
r'\bbtn-link\b': 'button--link',
|
|
|
|
# btn-close оставляем как есть (Bootstrap modal close)
|
|
}
|
|
|
|
def migrate_file(filepath):
|
|
"""Мигрировать один файл"""
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
original = content
|
|
|
|
# Применяем замены
|
|
for pattern, replacement in REPLACEMENTS.items():
|
|
content = re.sub(pattern, replacement, content)
|
|
|
|
# Если изменения есть
|
|
if content != original:
|
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
return True
|
|
return False
|
|
except Exception as e:
|
|
print(f"Error processing {filepath}: {e}")
|
|
return False
|
|
|
|
def main():
|
|
templates_dir = Path('templates')
|
|
|
|
# Найти все HTML файлы
|
|
html_files = list(templates_dir.rglob('*.html'))
|
|
|
|
print(f"Найдено {len(html_files)} HTML файлов")
|
|
print("Начинаем миграцию...\n")
|
|
|
|
changed_files = []
|
|
|
|
for filepath in html_files:
|
|
if migrate_file(filepath):
|
|
changed_files.append(filepath)
|
|
print(f"✓ {filepath}")
|
|
|
|
print(f"\n{'='*60}")
|
|
print(f"Миграция завершена!")
|
|
print(f"Обработано файлов: {len(html_files)}")
|
|
print(f"Изменено файлов: {len(changed_files)}")
|
|
print(f"{'='*60}")
|
|
|
|
if changed_files:
|
|
print("\nИзмененные файлы:")
|
|
for f in changed_files[:20]: # Показать первые 20
|
|
print(f" - {f}")
|
|
if len(changed_files) > 20:
|
|
print(f" ... и еще {len(changed_files) - 20} файлов")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|