feat: add Tailwind CSS configuration and build setup

- Add package.json with Tailwind dependencies
- Add tailwind.config.js and postcss.config.js
- Add source tailwind.css file
- Generate tailwind.output.css for admin and vendor
- Add Tailwind CSS documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-02 19:40:21 +01:00
parent d80659646f
commit da3d33a69c
8 changed files with 131455 additions and 2 deletions

View File

@@ -0,0 +1,313 @@
# Tailwind CSS Build Guide
**Version:** 1.0
**Last Updated:** December 2024
**Audience:** Frontend Developers
---
## Overview
The platform uses [Tailwind CSS](https://tailwindcss.com/) for styling with a **dual-layer architecture**:
1. **Base Layer (CDN):** Tailwind CSS v2.2.19 loaded via CDN with local fallback
2. **Override Layer (npm build):** Custom Windmill Dashboard theme built from Tailwind v1.4.6
This layered approach allows:
- Fast loading via CDN for base utilities
- Custom theme extensions (colors, dark mode, forms) via npm build
- Offline support via local fallback
> **Note:** A migration to Tailwind v3.4 is planned. See [Migration Plan](tailwind-migration-plan.md).
---
## Architecture
### How It Works
```
Browser loads:
1. CDN Tailwind 2.2.19 (base utilities)
└── Fallback: static/shared/css/tailwind.min.css
2. Custom tailwind.output.css (overrides/extensions)
└── Built from: static/admin/css/tailwind.css
└── Contains: Windmill Dashboard theme, custom colors, dark mode
```
### Key Files
| File | Version | Purpose |
|------|---------|---------|
| CDN `tailwindcss@2.2.19` | 2.2.19 | Base Tailwind utilities |
| `static/shared/css/tailwind.min.css` | 2.2.19 | Local fallback for CDN |
| `tailwind.config.js` | 1.4.6 | Custom build configuration |
| `static/admin/css/tailwind.css` | - | Source file with directives |
| `static/admin/css/tailwind.output.css` | 1.4.6 | Compiled custom styles |
| `static/vendor/css/tailwind.output.css` | 1.4.6 | Compiled custom styles |
### Template Loading Order
```html
<!-- 1. Base Tailwind from CDN (with fallback) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
onerror="this.onerror=null; this.href='/static/shared/css/tailwind.min.css';">
<!-- 2. Custom overrides (built via npm) -->
<link rel="stylesheet" href="/static/admin/css/tailwind.output.css" />
```
See [CDN Fallback Strategy](cdn-fallback-strategy.md) for details on offline support.
---
## How Tailwind Purging Works
Tailwind generates thousands of utility classes. To keep the CSS file small, it "purges" (removes) unused classes by scanning your source files.
### Content Paths
The `purge.content` array in `tailwind.config.js` tells Tailwind where to look for class usage:
```javascript
purge: {
content: [
'public/**/*.html',
'app/templates/**/*.html', // Jinja2 templates
'static/**/*.js', // Alpine.js components
],
// ...
}
```
### Safelist
Some classes are used dynamically in Alpine.js expressions and can't be detected by scanning. These must be added to the `safelist`:
```javascript
purge: {
content: [...],
safelist: [
'bg-orange-600',
'bg-green-600',
'bg-red-600',
'hover:bg-orange-700',
'hover:bg-green-700',
'hover:bg-red-700',
],
}
```
**When to add to safelist:**
- Classes used in Alpine.js `:class` bindings with dynamic conditions
- Classes constructed from variables (e.g., `bg-${color}-500`)
- Classes used only in JavaScript, not in HTML templates
---
## Building Tailwind CSS
### Prerequisites
Install Node.js dependencies (one-time setup):
```bash
npm install
```
Or using Make:
```bash
make npm-install
```
### Development Build
For development, build without purging (includes all classes, larger file):
```bash
# Build admin CSS
npm run tailwind:admin
# Build vendor CSS
npm run tailwind:vendor
# Or using Make
make tailwind-dev
```
### Production Build
For production, build with purging and minification (smaller file):
```bash
npm run build
# Or using Make
make tailwind-build
```
---
## Available npm Scripts
| Script | Command | Description |
|--------|---------|-------------|
| `npm run tailwind:admin` | Build admin CSS (dev) | Fast, includes all classes |
| `npm run tailwind:vendor` | Build vendor CSS (dev) | Fast, includes all classes |
| `npm run build:admin` | Build admin CSS (prod) | Purged and minified |
| `npm run build:vendor` | Build vendor CSS (prod) | Purged and minified |
| `npm run build` | Build all (prod) | Runs both production builds |
---
## Adding New Utility Classes
If you need a class that doesn't exist in the compiled CSS:
### Option 1: Check if it's being purged
The class might exist but is being removed. Add it to the `safelist` in `tailwind.config.js`:
```javascript
safelist: [
'your-new-class',
// ...
]
```
### Option 2: Extend the theme
Add custom values to `tailwind.config.js`:
```javascript
theme: {
extend: {
colors: {
'brand': '#123456',
},
spacing: {
'128': '32rem',
},
},
}
```
### Option 3: Rebuild CSS
After any config change, rebuild the CSS:
```bash
make tailwind-dev
```
---
## Troubleshooting
### Classes not appearing
1. **Check purge paths** - Ensure your file is in a scanned directory
2. **Check safelist** - Dynamic classes need to be safelisted
3. **Rebuild CSS** - Run `make tailwind-dev` after config changes
### Dynamic classes in Alpine.js
**Problem:** Classes in `:class` bindings may be purged.
```html
<!-- This class might be purged -->
<div :class="isActive ? 'bg-green-600' : 'bg-red-600'">
```
**Solution:** Add to safelist:
```javascript
safelist: ['bg-green-600', 'bg-red-600']
```
### Large CSS file in development
Development builds include all Tailwind classes (~1.2MB). This is normal.
Production builds purge unused classes, resulting in much smaller files (~50-100KB typically).
---
## Configuration Reference
### tailwind.config.js Structure
```javascript
module.exports = {
// Where to scan for class usage
purge: {
content: [...],
safelist: [...],
},
// Theme customization
theme: {
// Override defaults
colors: {...},
// Extend defaults
extend: {
fontFamily: {...},
maxHeight: {...},
},
},
// Variant configuration (hover, focus, dark mode, etc.)
variants: {
backgroundColor: ['hover', 'focus', 'dark', 'dark:hover'],
textColor: ['hover', 'dark'],
// ...
},
// Plugins
plugins: [
require('tailwindcss-multi-theme'),
require('@tailwindcss/custom-forms'),
],
}
```
### Dark Mode
The platform uses `tailwindcss-multi-theme` for dark mode. Dark mode classes use the `.theme-dark` parent selector:
```css
/* Light mode */
.bg-white { ... }
/* Dark mode */
.theme-dark .dark\:bg-gray-800 { ... }
```
---
## Best Practices
1. **Always rebuild after config changes**
```bash
make tailwind-dev
```
2. **Add dynamic classes to safelist** to prevent purging
3. **Use production builds for deployment** to minimize file size
4. **Check existing classes first** before adding custom ones - Tailwind likely has what you need
5. **Use consistent color scales** (e.g., `purple-600`, `purple-700`) for hover states
---
## Related Documentation
- [Frontend Overview](overview.md)
- [UI Components](shared/ui-components.md)
- [Tailwind CSS Official Docs](https://tailwindcss.com/docs)

View File

@@ -0,0 +1,361 @@
# Tailwind CSS Migration Plan: v1.4/v2.2 → v3.4
**Created:** December 2024
**Status:** Planned
**Estimated Time:** 2-3 hours
---
## Current State
### Two Tailwind Setups
| Component | Version | Source | Purpose |
|-----------|---------|--------|---------|
| Base styles | 2.2.19 | CDN + local fallback | Core Tailwind utilities for all frontends |
| Custom overrides | 1.4.6 | npm build | Windmill Dashboard theme (admin/vendor) |
### Current Files
```
package.json # tailwindcss: 1.4.6
tailwind.config.js # v1.4 format config
static/shared/css/tailwind.min.css # CDN fallback (v2.2.19)
static/admin/css/tailwind.output.css # Built overrides
static/vendor/css/tailwind.output.css # Built overrides
```
### Current Plugins
```json
{
"@tailwindcss/custom-forms": "0.2.1", // DEPRECATED in v3
"tailwindcss-multi-theme": "1.0.3" // May not work with v3
}
```
---
## Migration Goals
1. Upgrade npm Tailwind to v3.4.x (latest stable)
2. Upgrade CDN Tailwind to v3.4.x
3. Update local fallback file
4. Replace deprecated plugins
5. Update config to v3 format
6. Verify all frontends work correctly
---
## Step-by-Step Migration
### Phase 1: Backup Current State
```bash
# Create backup branch
git checkout -b backup/tailwind-v1.4
git add -A
git commit -m "Backup before Tailwind v3 migration"
git checkout master
# Create migration branch
git checkout -b feat/tailwind-v3-upgrade
```
### Phase 2: Update npm Dependencies
```bash
# Remove old packages
npm uninstall tailwindcss tailwindcss-multi-theme @tailwindcss/custom-forms
# Install new packages
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npm install -D @tailwindcss/forms @tailwindcss/typography
# Verify versions
npm list tailwindcss
```
**Expected versions:**
- tailwindcss: ^3.4.x
- postcss: ^8.4.x
- autoprefixer: ^10.4.x
### Phase 3: Update tailwind.config.js
Replace the entire config file:
```javascript
// tailwind.config.js - Tailwind CSS v3.4
/** @type {import('tailwindcss').Config} */
module.exports = {
// v3: 'content' replaces 'purge'
content: [
'app/templates/**/*.html',
'static/**/*.js',
],
// v3: safelist for dynamic classes
safelist: [
'bg-orange-600',
'bg-green-600',
'bg-red-600',
'hover:bg-orange-700',
'hover:bg-green-700',
'hover:bg-red-700',
// Add any other dynamic classes used in Alpine.js
],
// v3: darkMode replaces tailwindcss-multi-theme
darkMode: 'class', // or 'media' for OS preference
theme: {
extend: {
// Custom colors from Windmill Dashboard
colors: {
gray: {
50: '#f9fafb',
100: '#f4f5f7',
200: '#e5e7eb',
300: '#d5d6d7',
400: '#9e9e9e',
500: '#707275',
600: '#4c4f52',
700: '#24262d',
800: '#1a1c23',
900: '#121317',
},
purple: {
50: '#f6f5ff',
100: '#edebfe',
200: '#dcd7fe',
300: '#cabffd',
400: '#ac94fa',
500: '#9061f9',
600: '#7e3af2',
700: '#6c2bd9',
800: '#5521b5',
900: '#4a1d96',
},
// Add other custom colors as needed
},
fontFamily: {
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
},
maxHeight: {
'xl': '36rem',
},
},
},
plugins: [
require('@tailwindcss/forms'), // Replaces @tailwindcss/custom-forms
require('@tailwindcss/typography'), // Optional: for prose content
],
}
```
### Phase 4: Update CSS Source File
Update `static/admin/css/tailwind.css`:
```css
/* Tailwind CSS v3 directives */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Custom component classes if needed */
@layer components {
.form-input {
@apply block w-full rounded-md border-gray-300 shadow-sm
focus:border-purple-500 focus:ring-purple-500;
}
.form-select {
@apply block w-full rounded-md border-gray-300 shadow-sm
focus:border-purple-500 focus:ring-purple-500;
}
.form-checkbox {
@apply rounded border-gray-300 text-purple-600
focus:ring-purple-500;
}
}
```
### Phase 5: Update postcss.config.js
```javascript
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
}
}
```
### Phase 6: Update package.json Scripts
```json
{
"scripts": {
"tailwind:admin": "npx tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css",
"tailwind:vendor": "npx tailwindcss -i static/admin/css/tailwind.css -o static/vendor/css/tailwind.output.css",
"tailwind:watch": "npx tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css --watch",
"build:admin": "npx tailwindcss -i static/admin/css/tailwind.css -o static/admin/css/tailwind.output.css --minify",
"build:vendor": "npx tailwindcss -i static/admin/css/tailwind.css -o static/vendor/css/tailwind.output.css --minify",
"build": "npm run build:admin && npm run build:vendor"
}
}
```
### Phase 7: Update Dark Mode Implementation
**Old approach (tailwindcss-multi-theme):**
```html
<body class="theme-dark">
<div class="bg-white dark:bg-gray-800">
```
**New approach (Tailwind v3 native):**
```html
<body class="dark">
<div class="bg-white dark:bg-gray-800">
```
**Files to update:**
1. `app/templates/admin/base.html` - Change `theme-dark` to `dark`
2. `app/templates/vendor/base.html` - Change `theme-dark` to `dark`
3. `static/admin/js/init-alpine.js` - Update dark mode toggle logic
4. `static/vendor/js/init-alpine.js` - Update dark mode toggle logic
**JavaScript update example:**
```javascript
// Old
document.body.classList.toggle('theme-dark');
// New
document.documentElement.classList.toggle('dark');
```
### Phase 8: Update CDN and Local Fallback
**Option A: Use Tailwind Play CDN (development only)**
```html
<script src="https://cdn.tailwindcss.com"></script>
```
**Option B: Build and serve locally (recommended for production)**
Since Tailwind v3 doesn't have a pre-built CDN CSS file (it's JIT-only), the recommended approach is:
1. Remove CDN loading from templates
2. Load only the built `tailwind.output.css`
3. Include all needed utilities in your build
**Update base templates:**
```html
<!-- OLD: CDN with fallback -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/tailwind.min.css') }}';">
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />
<!-- NEW: Local only (v3) -->
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />
```
### Phase 9: Build and Test
```bash
# Install dependencies
npm install
# Build CSS
npm run tailwind:admin
npm run tailwind:vendor
# Start development server
make dev
# Test all frontends:
# - http://localhost:8000/admin/dashboard
# - http://localhost:8000/vendor/{code}/dashboard
# - http://localhost:8000/ (shop)
```
### Phase 10: Verify Checklist
- [ ] Admin dashboard loads correctly
- [ ] Vendor dashboard loads correctly
- [ ] Shop frontend loads correctly
- [ ] Dark mode toggle works
- [ ] All buttons have correct colors
- [ ] Forms display correctly (inputs, selects, checkboxes)
- [ ] Responsive design works (mobile/tablet/desktop)
- [ ] No console errors
- [ ] Production build works (`npm run build`)
---
## Breaking Changes Reference
### Class Name Changes (v2 → v3)
| v2.x | v3.x | Notes |
|------|------|-------|
| `overflow-ellipsis` | `text-ellipsis` | Renamed |
| `flex-grow-0` | `grow-0` | Shortened |
| `flex-shrink-0` | `shrink-0` | Shortened |
| `decoration-clone` | `box-decoration-clone` | Renamed |
### Plugin Changes
| Old Plugin | New Plugin | Notes |
|------------|------------|-------|
| `@tailwindcss/custom-forms` | `@tailwindcss/forms` | Complete rewrite |
| `tailwindcss-multi-theme` | Built-in `darkMode: 'class'` | Native support |
### Config Changes
| v1.x/v2.x | v3.x |
|-----------|------|
| `purge: [...]` | `content: [...]` |
| `variants: {...}` | Removed (JIT generates all) |
| `mode: 'jit'` | Default (not needed) |
---
## Rollback Plan
If issues arise:
```bash
# Switch back to backup branch
git checkout backup/tailwind-v1.4
# Or reset changes
git checkout master
git reset --hard HEAD~1
```
---
## Post-Migration Tasks
1. Update `docs/frontend/tailwind-css.md` with v3 information
2. Update `docs/frontend/cdn-fallback-strategy.md` (or remove CDN references)
3. Remove `static/shared/css/tailwind.min.css` if no longer needed
4. Update any documentation referencing old class names
5. Consider adding Tailwind IntelliSense VS Code extension config
---
## Resources
- [Tailwind CSS v3 Upgrade Guide](https://tailwindcss.com/docs/upgrade-guide)
- [Tailwind CSS v3 Documentation](https://tailwindcss.com/docs)
- [@tailwindcss/forms Plugin](https://github.com/tailwindlabs/tailwindcss-forms)
- [Dark Mode in Tailwind v3](https://tailwindcss.com/docs/dark-mode)