mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
543 lines
13 KiB
Markdown
543 lines
13 KiB
Markdown
# 🎨 MyUIbrix CSS Architecture Guide
|
|
|
|
## 📋 Overview
|
|
|
|
Your project uses a **hybrid CSS approach** combining **Chakra UI** (CSS-in-JS) with **traditional CSS files**. Here's how CSS works with MyUIbrix and your elements.
|
|
|
|
---
|
|
|
|
## 🏗️ Current CSS Architecture
|
|
|
|
### 1. **Chakra UI (Primary Styling System)**
|
|
```typescript
|
|
// From package.json
|
|
"@chakra-ui/react": "^2.8.2"
|
|
"@emotion/react": "^11.11.1" // Chakra's CSS-in-JS engine
|
|
"@emotion/styled": "^11.11.0"
|
|
```
|
|
|
|
**How it works:**
|
|
- Chakra UI uses **@emotion** for CSS-in-JS
|
|
- Styles are written as **props** directly on components
|
|
- No separate CSS files needed for Chakra components
|
|
|
|
**Example from your code:**
|
|
```tsx
|
|
<Box bg="white" p={4} borderRadius="xl" boxShadow="sm">
|
|
<Heading size="lg" mb={4} color="blue.500">
|
|
Title
|
|
</Heading>
|
|
</Box>
|
|
```
|
|
|
|
---
|
|
|
|
### 2. **Global CSS Files (Imported at App Level)**
|
|
```typescript
|
|
// From index.tsx
|
|
import './index.css';
|
|
import './styles/global-enhancements.css';
|
|
import './styles/admin-enhancements.css';
|
|
```
|
|
|
|
**Your current CSS files:**
|
|
```
|
|
frontend/src/styles/
|
|
├── admin-enhancements.css # Admin-specific styles
|
|
├── custom-editor.css # Rich editor styles
|
|
├── designSystem.css # Design system
|
|
├── designSystem.module.css # Modular design system
|
|
├── global-enhancements.css # Global utilities
|
|
├── globals.css # Base globals
|
|
├── logos.css # Logo styling
|
|
├── sparta-styles.css # ⚽ NEW: Sparta elements
|
|
└── theme.css # Theme variables
|
|
```
|
|
|
|
**When loaded:** Once at app startup
|
|
**Scope:** Global - available everywhere
|
|
**Use case:** Global utilities, resets, theme variables
|
|
|
|
---
|
|
|
|
### 3. **Page-Specific CSS Files**
|
|
```typescript
|
|
// From HomePage.tsx
|
|
import '../styles/theme.css';
|
|
import './styles/UnifiedHome.css';
|
|
```
|
|
|
|
**When loaded:** When the specific page/component mounts
|
|
**Scope:** Global (but only loaded when needed)
|
|
**Use case:** Page-specific complex layouts
|
|
|
|
---
|
|
|
|
### 4. **Component-Scoped CSS Classes**
|
|
```tsx
|
|
// Using className with global CSS
|
|
<Box className="sparta-slider-container sparta-container">
|
|
<Heading className="sparta-slider-title">Videos</Heading>
|
|
</Box>
|
|
```
|
|
|
|
**When loaded:** CSS file must be imported somewhere in the component tree
|
|
**Scope:** Global classes, but named to avoid conflicts
|
|
**Use case:** Complex component styling with custom animations
|
|
|
|
---
|
|
|
|
## ⚽ How Sparta CSS Works with MyUIbrix
|
|
|
|
### Current Approach (What I Created)
|
|
|
|
#### **Option 1: Global Import (Recommended for now)**
|
|
```typescript
|
|
// In App.tsx or index.tsx
|
|
import './styles/sparta-styles.css';
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Simple - one import, works everywhere
|
|
- ✅ All Sparta elements have access to styles
|
|
- ✅ No duplicate CSS
|
|
- ✅ Easy to maintain
|
|
|
|
**Cons:**
|
|
- ⚠️ CSS bundle is always loaded (even if Sparta elements not used)
|
|
- ⚠️ Global namespace (but we use BEM-style naming to avoid conflicts)
|
|
|
|
---
|
|
|
|
#### **Option 2: Component-Level Import (Alternative)**
|
|
```tsx
|
|
// In each Sparta component
|
|
import '../../styles/sparta-styles.css';
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ CSS only loaded when component is used
|
|
- ✅ Co-located with component
|
|
|
|
**Cons:**
|
|
- ⚠️ If multiple Sparta components used, CSS imported multiple times
|
|
- ⚠️ Webpack/React handles deduplication, but more imports to manage
|
|
|
|
---
|
|
|
|
#### **Option 3: Split into Modular Files (Best for Production)**
|
|
```
|
|
frontend/src/styles/sparta/
|
|
├── sparta-navbar.css
|
|
├── sparta-hero.css
|
|
├── sparta-slider.css
|
|
├── sparta-tabs.css
|
|
├── sparta-products.css
|
|
├── sparta-footer.css
|
|
└── sparta-utilities.css
|
|
```
|
|
|
|
```tsx
|
|
// In each component
|
|
import '../../styles/sparta/sparta-slider.css';
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Only load CSS for components actually used
|
|
- ✅ Smaller bundle per component
|
|
- ✅ Better code splitting
|
|
|
|
**Cons:**
|
|
- ⚠️ More files to manage
|
|
- ⚠️ Need to track dependencies (utilities used by multiple)
|
|
|
|
---
|
|
|
|
## 🔧 MyUIbrix Element Styling Patterns
|
|
|
|
### Pattern A: Pure Chakra UI (Current MyUIbrix Style)
|
|
```tsx
|
|
// No CSS files needed
|
|
const MyElement = () => (
|
|
<Box bg="gray.800" p={4} borderRadius="md">
|
|
<Heading size="lg" color="white">Title</Heading>
|
|
<Text color="gray.400">Description</Text>
|
|
</Box>
|
|
);
|
|
```
|
|
|
|
**Used for:**
|
|
- Simple layouts
|
|
- Admin interfaces
|
|
- Form elements
|
|
- Most existing MyUIbrix UI
|
|
|
|
---
|
|
|
|
### Pattern B: Chakra + Custom Classes (Sparta Elements)
|
|
```tsx
|
|
// Import CSS file
|
|
import '../../styles/sparta-styles.css';
|
|
|
|
const SpartaElement = () => (
|
|
<Box className="sparta-slider-container sparta-section">
|
|
<Heading className="sparta-slider-title" as="h2">
|
|
Videos
|
|
</Heading>
|
|
<Flex className="sparta-slider-track" gap={4}>
|
|
{/* slides */}
|
|
</Flex>
|
|
</Box>
|
|
);
|
|
```
|
|
|
|
**Used for:**
|
|
- Complex animations
|
|
- Specific design systems (Sparta)
|
|
- Custom hover effects
|
|
- Pseudo-elements (::before, ::after)
|
|
|
|
**Why?** Some CSS features aren't easily done in Chakra:
|
|
- CSS animations with keyframes
|
|
- Complex pseudo-elements
|
|
- Gradient overlays with position
|
|
- Transform-based animations
|
|
|
|
---
|
|
|
|
### Pattern C: CSS Modules (Not currently used, but available)
|
|
```tsx
|
|
// sparta-slider.module.css
|
|
import styles from './sparta-slider.module.css';
|
|
|
|
const SpartaSlider = () => (
|
|
<div className={styles.container}>
|
|
<h2 className={styles.title}>Videos</h2>
|
|
</div>
|
|
);
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Scoped CSS (no global namespace pollution)
|
|
- ✅ Auto-generated unique class names
|
|
|
|
**Cons:**
|
|
- ⚠️ Not used in your current setup
|
|
- ⚠️ Would require refactoring
|
|
|
|
---
|
|
|
|
## 🎯 Recommended Approach for Sparta Elements
|
|
|
|
### **For Development/Testing (Current)**
|
|
```typescript
|
|
// In App.tsx or index.tsx (ONE TIME)
|
|
import './styles/sparta-styles.css';
|
|
```
|
|
|
|
Then use classes in components:
|
|
```tsx
|
|
<Box className="sparta-slider-container">
|
|
<Heading className="sparta-slider-title">Videos</Heading>
|
|
</Box>
|
|
```
|
|
|
|
---
|
|
|
|
### **For Production (Optimized)**
|
|
|
|
#### Step 1: Split CSS file
|
|
```bash
|
|
# Create modular files
|
|
frontend/src/styles/sparta/
|
|
├── _base.css # Variables, resets
|
|
├── navbar.css # Just navbar styles
|
|
├── hero.css # Just hero styles
|
|
├── slider.css # Just slider styles
|
|
├── tabs.css # Just tabs styles
|
|
├── products.css # Just product styles
|
|
├── footer.css # Just footer styles
|
|
└── utilities.css # Shared utilities
|
|
```
|
|
|
|
#### Step 2: Import in components
|
|
```tsx
|
|
// SpartaHorizontalSlider.tsx
|
|
import '../../styles/sparta/_base.css'; // Variables
|
|
import '../../styles/sparta/slider.css'; // Component styles
|
|
import '../../styles/sparta/utilities.css'; // Shared utilities
|
|
|
|
const SpartaHorizontalSlider = () => (
|
|
<Box className="sparta-slider-container">
|
|
{/* ... */}
|
|
</Box>
|
|
);
|
|
```
|
|
|
|
#### Step 3: Dynamic loading via MyUIbrix settings
|
|
```tsx
|
|
// In HomePage or element renderer
|
|
const loadSpartaStyles = (variant: string) => {
|
|
if (variant === 'sparta_horizontal_slider') {
|
|
import('../../styles/sparta/slider.css');
|
|
}
|
|
if (variant === 'sparta_navbar') {
|
|
import('../../styles/sparta/navbar.css');
|
|
}
|
|
// ... etc
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Integration with MyUIbrix Editor
|
|
|
|
### How Page Elements Use Styles
|
|
|
|
```typescript
|
|
// From pageElements.ts
|
|
export interface PageElementConfig {
|
|
id?: number;
|
|
page_type: string;
|
|
element_name: string;
|
|
variant: string; // ← This determines which CSS to load
|
|
visible?: boolean;
|
|
display_order?: number;
|
|
settings?: Record<string, any>;
|
|
}
|
|
```
|
|
|
|
### Example Element Renderer
|
|
|
|
```tsx
|
|
// Pseudo-code for rendering elements
|
|
const renderElement = (config: PageElementConfig) => {
|
|
const { element_name, variant, settings } = config;
|
|
|
|
// Determine component and styles based on variant
|
|
switch (variant) {
|
|
case 'sparta_horizontal_slider':
|
|
return <SpartaHorizontalSlider {...settings} />;
|
|
// CSS already imported in component or globally
|
|
|
|
case 'sparta_navbar':
|
|
return <SpartaNavbar {...settings} />;
|
|
|
|
default:
|
|
return <DefaultElement {...settings} />;
|
|
}
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 📦 CSS Loading Strategies
|
|
|
|
### Strategy 1: Global Load (Simplest)
|
|
```typescript
|
|
// index.tsx or App.tsx
|
|
import './styles/sparta-styles.css';
|
|
```
|
|
|
|
**Bundle size:** ~16KB (sparta-styles.css)
|
|
**When:** Always loaded
|
|
**Best for:** Small projects, development
|
|
|
|
---
|
|
|
|
### Strategy 2: Route-Based (Code Splitting)
|
|
```typescript
|
|
// HomePage.tsx
|
|
import './styles/sparta-styles.css';
|
|
|
|
// BlogPage.tsx - doesn't import it
|
|
```
|
|
|
|
**Bundle size:** Only loaded on pages that need it
|
|
**When:** When route is accessed
|
|
**Best for:** Medium projects
|
|
|
|
---
|
|
|
|
### Strategy 3: Component-Based (Granular)
|
|
```typescript
|
|
// SpartaHorizontalSlider.tsx
|
|
import '../../styles/sparta/slider.css';
|
|
|
|
// SpartaNavbar.tsx
|
|
import '../../styles/sparta/navbar.css';
|
|
```
|
|
|
|
**Bundle size:** Only load what's used
|
|
**When:** When component mounts
|
|
**Best for:** Large projects, optimal performance
|
|
|
|
---
|
|
|
|
### Strategy 4: Dynamic Import (Advanced)
|
|
```typescript
|
|
// Element renderer
|
|
const loadElementStyles = async (variant: string) => {
|
|
switch (variant) {
|
|
case 'sparta_horizontal_slider':
|
|
await import('../../styles/sparta/slider.css');
|
|
break;
|
|
case 'sparta_navbar':
|
|
await import('../../styles/sparta/navbar.css');
|
|
break;
|
|
}
|
|
};
|
|
|
|
// Before rendering
|
|
await loadElementStyles(config.variant);
|
|
```
|
|
|
|
**Bundle size:** Smallest possible
|
|
**When:** On-demand
|
|
**Best for:** Maximum optimization
|
|
|
|
---
|
|
|
|
## 🎨 CSS Variables in Sparta Styles
|
|
|
|
### Using CSS Custom Properties
|
|
```css
|
|
/* sparta-styles.css */
|
|
.sparta-slider-container {
|
|
background: var(--colorBgPrimary, #0e0e0e);
|
|
color: var(--colorTextPrimary, #ffffff);
|
|
}
|
|
```
|
|
|
|
### Setting Variables from MyUIbrix
|
|
```tsx
|
|
// In settings or theme
|
|
const spartaTheme = {
|
|
colorBgPrimary: '#0e0e0e',
|
|
colorAccent: '#f03232',
|
|
colorTextPrimary: '#ffffff',
|
|
};
|
|
|
|
// Apply to element
|
|
<Box
|
|
className="sparta-slider-container"
|
|
style={{
|
|
'--colorAccent': spartaTheme.colorAccent,
|
|
} as React.CSSProperties}
|
|
>
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Migration Path
|
|
|
|
### Current State
|
|
```
|
|
✅ Chakra UI everywhere
|
|
✅ Global CSS files for complex styles
|
|
✅ sparta-styles.css created but not imported
|
|
```
|
|
|
|
### Step 1: Add Sparta CSS (Now)
|
|
```typescript
|
|
// App.tsx
|
|
import './styles/sparta-styles.css';
|
|
```
|
|
|
|
### Step 2: Test Sparta Elements
|
|
```tsx
|
|
// Use in components
|
|
<Box className="sparta-slider-container">
|
|
{/* Uses global CSS */}
|
|
</Box>
|
|
```
|
|
|
|
### Step 3: Optimize (Later)
|
|
- Split into modular files
|
|
- Implement dynamic imports
|
|
- Add CSS purging in production
|
|
|
|
---
|
|
|
|
## 📊 Comparison Table
|
|
|
|
| Approach | Bundle Size | Ease of Use | Performance | Maintenance |
|
|
|----------|-------------|-------------|-------------|-------------|
|
|
| **Chakra Only** | Small | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
|
| **Global CSS** | Medium | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
|
|
| **Component CSS** | Small | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
|
|
| **CSS Modules** | Small | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
|
|
| **Dynamic Import** | Smallest | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
|
|
|
|
---
|
|
|
|
## ✅ Recommendation
|
|
|
|
### **For Now (Development)**
|
|
```typescript
|
|
// 1. Import globally in App.tsx
|
|
import './styles/sparta-styles.css';
|
|
|
|
// 2. Use classes in components
|
|
<Box className="sparta-slider-container">
|
|
<Heading className="sparta-slider-title">Videos</Heading>
|
|
</Box>
|
|
```
|
|
|
|
### **For Later (Production)**
|
|
1. Split `sparta-styles.css` into modular files
|
|
2. Import per-component
|
|
3. Add dynamic loading based on `variant`
|
|
4. Implement CSS purging (remove unused styles)
|
|
|
|
---
|
|
|
|
## 🎯 Quick Start
|
|
|
|
### Option 1: Add to App.tsx (Recommended)
|
|
```typescript
|
|
// frontend/src/App.tsx
|
|
import './styles/sparta-styles.css'; // Add this line
|
|
```
|
|
|
|
### Option 2: Add to index.tsx
|
|
```typescript
|
|
// frontend/src/index.tsx
|
|
import './styles/sparta-styles.css'; // Add this line
|
|
```
|
|
|
|
### Option 3: Import in Component
|
|
```typescript
|
|
// SpartaHorizontalSlider.tsx - already has this
|
|
import '../../styles/sparta-styles.css';
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Summary
|
|
|
|
**How CSS works with MyUIbrix:**
|
|
|
|
1. **Primary:** Chakra UI (CSS-in-JS via @emotion)
|
|
2. **Secondary:** Global CSS files for complex styles
|
|
3. **Sparta Elements:** Custom CSS classes + Chakra UI hybrid
|
|
|
|
**Best practice:**
|
|
- Use **Chakra UI props** for simple styling
|
|
- Use **custom CSS classes** for complex animations/layouts
|
|
- Import CSS **globally** for development, **per-component** for production
|
|
|
|
**Current setup:**
|
|
- ✅ Sparta CSS file created (`sparta-styles.css`)
|
|
- ⏳ Need to import it (one line in App.tsx or index.tsx)
|
|
- ✅ Classes already used in `SpartaHorizontalSlider.tsx`
|
|
|
|
**Next step:**
|
|
Add one import statement and you're ready to use all Sparta elements! 🚀
|
|
|
|
---
|
|
|
|
**Created:** October 15, 2025
|
|
**Version:** 1.0.0
|
|
**Status:** ✅ Ready to implement
|