Revert "feat: update TODO and enhance design token integration"
This reverts commit aa348a0f82.
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/*
|
||||
* CSS Variables - Design Tokens
|
||||
*
|
||||
* Ces variables sont synchronisées avec src/lib/design-tokens.ts
|
||||
* Pour modifier les couleurs, utilisez les design tokens plutôt que ce fichier directement.
|
||||
*
|
||||
* Documentation: src/lib/DESIGN_SYSTEM.md
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* Valeurs par défaut (Light theme) */
|
||||
--background: #f1f5f9; /* slate-100 */
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Card, CardContent } from '@/components/ui/Card';
|
||||
import { StatusMessage } from '@/components/ui/StatusMessage';
|
||||
import { useDesignTokens } from '@/hooks/useDesignTokens';
|
||||
|
||||
interface Message {
|
||||
type: 'success' | 'error';
|
||||
@@ -29,7 +27,6 @@ export function QuickActions({
|
||||
jiraEnabled,
|
||||
messages
|
||||
}: QuickActionsProps) {
|
||||
const { styles } = useDesignTokens();
|
||||
return (
|
||||
<div className="mt-8">
|
||||
<h2 className="text-xl font-semibold text-[var(--foreground)] mb-4">
|
||||
@@ -46,18 +43,17 @@ export function QuickActions({
|
||||
Créer une sauvegarde des données
|
||||
</p>
|
||||
{messages.backup && (
|
||||
<div className="mt-2">
|
||||
<StatusMessage type={messages.backup.type}>
|
||||
{messages.backup.text}
|
||||
</StatusMessage>
|
||||
</div>
|
||||
<p className="text-xs mt-1" style={{
|
||||
color: messages.backup.type === 'success' ? 'var(--success)' : 'var(--destructive)'
|
||||
}}>
|
||||
{messages.backup.text}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={onCreateBackup}
|
||||
disabled={isBackupLoading}
|
||||
className="px-3 py-1.5 rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
style={styles.primaryButton}
|
||||
className="px-3 py-1.5 bg-[var(--primary)] text-[var(--primary-foreground)] rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isBackupLoading ? 'En cours...' : 'Sauvegarder'}
|
||||
</button>
|
||||
@@ -74,18 +70,17 @@ export function QuickActions({
|
||||
Tester la connexion Jira
|
||||
</p>
|
||||
{messages.jira && (
|
||||
<div className="mt-2">
|
||||
<StatusMessage type={messages.jira.type}>
|
||||
{messages.jira.text}
|
||||
</StatusMessage>
|
||||
</div>
|
||||
<p className="text-xs mt-1" style={{
|
||||
color: messages.jira.type === 'success' ? 'var(--success)' : 'var(--destructive)'
|
||||
}}>
|
||||
{messages.jira.text}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={onTestJira}
|
||||
disabled={!jiraEnabled || isJiraTestLoading}
|
||||
className="px-3 py-1.5 rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
style={styles.input}
|
||||
className="px-3 py-1.5 bg-[var(--card)] text-[var(--foreground)] border border-[var(--border)] rounded text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isJiraTestLoading ? 'Test...' : 'Tester'}
|
||||
</button>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Composant de carte colorée utilisant les design tokens
|
||||
*/
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import { useDesignTokens } from '@/hooks/useDesignTokens';
|
||||
|
||||
interface ColoredCardProps {
|
||||
color: 'primary' | 'purple' | 'yellow' | 'green' | 'blue' | 'gray';
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
hover?: boolean;
|
||||
}
|
||||
|
||||
export function ColoredCard({ color, children, className = '', hover = true }: ColoredCardProps) {
|
||||
const { styles } = useDesignTokens();
|
||||
|
||||
const getStyle = () => {
|
||||
switch (color) {
|
||||
case 'primary':
|
||||
return styles.primaryCard;
|
||||
case 'purple':
|
||||
return styles.purpleCard;
|
||||
case 'yellow':
|
||||
return styles.yellowCard;
|
||||
case 'green':
|
||||
return {
|
||||
color: 'var(--green)',
|
||||
backgroundColor: 'color-mix(in srgb, var(--green) 10%, transparent)',
|
||||
borderColor: 'color-mix(in srgb, var(--green) 20%, var(--border))',
|
||||
};
|
||||
case 'blue':
|
||||
return {
|
||||
color: 'var(--blue)',
|
||||
backgroundColor: 'color-mix(in srgb, var(--blue) 10%, transparent)',
|
||||
borderColor: 'color-mix(in srgb, var(--blue) 20%, var(--border))',
|
||||
};
|
||||
case 'gray':
|
||||
return {
|
||||
color: 'var(--muted-foreground)',
|
||||
backgroundColor: 'color-mix(in srgb, var(--muted) 10%, transparent)',
|
||||
borderColor: 'color-mix(in srgb, var(--muted) 20%, var(--border))',
|
||||
};
|
||||
default:
|
||||
return styles.primaryCard;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`p-4 rounded-lg border transition-all ${hover ? 'hover:shadow-sm hover:scale-[1.01]' : ''} ${className}`}
|
||||
style={getStyle()}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Composant pour afficher des messages d'état avec les design tokens
|
||||
*/
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import { useDesignTokens } from '@/hooks/useDesignTokens';
|
||||
|
||||
interface StatusMessageProps {
|
||||
type: 'success' | 'error' | 'warning' | 'info';
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function StatusMessage({ type, children, className = '' }: StatusMessageProps) {
|
||||
const { styles } = useDesignTokens();
|
||||
|
||||
const getStyle = () => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return styles.successMessage;
|
||||
case 'error':
|
||||
return styles.errorMessage;
|
||||
case 'warning':
|
||||
return styles.warningMessage;
|
||||
case 'info':
|
||||
return styles.primaryCard;
|
||||
default:
|
||||
return styles.primaryCard;
|
||||
}
|
||||
};
|
||||
|
||||
const getIcon = () => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return '✅';
|
||||
case 'error':
|
||||
return '❌';
|
||||
case 'warning':
|
||||
return '⚠️';
|
||||
case 'info':
|
||||
return 'ℹ️';
|
||||
default:
|
||||
return 'ℹ️';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`p-3 rounded border ${className}`}
|
||||
style={getStyle()}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{getIcon()}</span>
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* Hook pour utiliser les design tokens dans les composants
|
||||
*/
|
||||
|
||||
import { useTheme } from '@/contexts/ThemeContext';
|
||||
import { DesignTokenUtils, COLOR_PATTERNS, OPACITY } from '@/lib/design-tokens';
|
||||
|
||||
export function useDesignTokens() {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return {
|
||||
theme,
|
||||
|
||||
// Utilitaires de couleur
|
||||
withOpacity: DesignTokenUtils.withOpacity,
|
||||
borderWithOpacity: DesignTokenUtils.borderWithOpacity,
|
||||
backgroundWithOpacity: DesignTokenUtils.backgroundWithOpacity,
|
||||
|
||||
// Patterns prédéfinis
|
||||
patterns: COLOR_PATTERNS,
|
||||
|
||||
// Opacités courantes
|
||||
opacity: OPACITY,
|
||||
|
||||
// Couleurs CSS Variables (pour usage direct)
|
||||
colors: {
|
||||
background: 'var(--background)',
|
||||
foreground: 'var(--foreground)',
|
||||
card: 'var(--card)',
|
||||
cardHover: 'var(--card-hover)',
|
||||
cardColumn: 'var(--card-column)',
|
||||
border: 'var(--border)',
|
||||
input: 'var(--input)',
|
||||
primary: 'var(--primary)',
|
||||
primaryForeground: 'var(--primary-foreground)',
|
||||
muted: 'var(--muted)',
|
||||
mutedForeground: 'var(--muted-foreground)',
|
||||
destructive: 'var(--destructive)',
|
||||
success: 'var(--success)',
|
||||
accent: 'var(--accent)',
|
||||
purple: 'var(--purple)',
|
||||
yellow: 'var(--yellow)',
|
||||
green: 'var(--green)',
|
||||
blue: 'var(--blue)',
|
||||
gray: 'var(--gray)',
|
||||
grayLight: 'var(--gray-light)',
|
||||
},
|
||||
|
||||
// Styles prédéfinis pour les composants courants
|
||||
styles: {
|
||||
// Messages d'état
|
||||
successMessage: {
|
||||
color: COLOR_PATTERNS.success.text,
|
||||
backgroundColor: COLOR_PATTERNS.success.background,
|
||||
borderColor: COLOR_PATTERNS.success.border,
|
||||
},
|
||||
errorMessage: {
|
||||
color: COLOR_PATTERNS.error.text,
|
||||
backgroundColor: COLOR_PATTERNS.error.background,
|
||||
borderColor: COLOR_PATTERNS.error.border,
|
||||
},
|
||||
warningMessage: {
|
||||
color: COLOR_PATTERNS.warning.text,
|
||||
backgroundColor: COLOR_PATTERNS.warning.background,
|
||||
borderColor: COLOR_PATTERNS.warning.border,
|
||||
},
|
||||
|
||||
// Cards colorées
|
||||
primaryCard: {
|
||||
color: COLOR_PATTERNS.primary.text,
|
||||
backgroundColor: COLOR_PATTERNS.primary.background,
|
||||
borderColor: COLOR_PATTERNS.primary.border,
|
||||
},
|
||||
purpleCard: {
|
||||
color: COLOR_PATTERNS.purple.text,
|
||||
backgroundColor: COLOR_PATTERNS.purple.background,
|
||||
borderColor: COLOR_PATTERNS.purple.border,
|
||||
},
|
||||
yellowCard: {
|
||||
color: COLOR_PATTERNS.yellow.text,
|
||||
backgroundColor: COLOR_PATTERNS.yellow.background,
|
||||
borderColor: COLOR_PATTERNS.yellow.border,
|
||||
},
|
||||
|
||||
// Boutons
|
||||
primaryButton: {
|
||||
backgroundColor: 'var(--primary)',
|
||||
color: 'var(--primary-foreground)',
|
||||
borderColor: 'var(--primary)',
|
||||
},
|
||||
destructiveButton: {
|
||||
backgroundColor: 'var(--destructive)',
|
||||
color: 'white',
|
||||
borderColor: 'var(--destructive)',
|
||||
},
|
||||
|
||||
// Inputs
|
||||
input: {
|
||||
backgroundColor: 'var(--input)',
|
||||
borderColor: 'var(--border)',
|
||||
color: 'var(--foreground)',
|
||||
},
|
||||
|
||||
// Scrollbars
|
||||
scrollbar: {
|
||||
track: 'var(--card)',
|
||||
thumb: 'var(--muted)',
|
||||
thumbHover: 'var(--primary)',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
# Design System - TowerControl
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Le design system de TowerControl utilise des **Design Tokens** pour assurer la cohérence visuelle et faciliter la maintenance des couleurs et styles.
|
||||
|
||||
## Architecture
|
||||
|
||||
### 1. Design Tokens (`src/lib/design-tokens.ts`)
|
||||
|
||||
Source unique de vérité pour toutes les couleurs et styles :
|
||||
|
||||
```typescript
|
||||
import { DesignTokenUtils, COLOR_PATTERNS } from '@/lib/design-tokens';
|
||||
|
||||
// Utilisation des utilitaires
|
||||
const backgroundColor = DesignTokenUtils.withOpacity('var(--primary)', 0.1);
|
||||
const borderColor = DesignTokenUtils.borderWithOpacity('var(--success)', 0.2, 'var(--border)');
|
||||
```
|
||||
|
||||
### 2. Hook useDesignTokens (`src/hooks/useDesignTokens.ts`)
|
||||
|
||||
Hook React pour utiliser facilement les tokens dans les composants :
|
||||
|
||||
```tsx
|
||||
import { useDesignTokens } from '@/hooks/useDesignTokens';
|
||||
|
||||
function MyComponent() {
|
||||
const { colors, styles, patterns } = useDesignTokens();
|
||||
|
||||
return (
|
||||
<div style={{ color: colors.primary }}>
|
||||
<div style={styles.successMessage}>Succès !</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Composants utilitaires
|
||||
|
||||
#### StatusMessage
|
||||
```tsx
|
||||
import { StatusMessage } from '@/components/ui/StatusMessage';
|
||||
|
||||
<StatusMessage type="success">Opération réussie</StatusMessage>
|
||||
<StatusMessage type="error">Une erreur est survenue</StatusMessage>
|
||||
<StatusMessage type="warning">Attention requise</StatusMessage>
|
||||
<StatusMessage type="info">Information</StatusMessage>
|
||||
```
|
||||
|
||||
#### ColoredCard
|
||||
```tsx
|
||||
import { ColoredCard } from '@/components/ui/ColoredCard';
|
||||
|
||||
<ColoredCard color="primary">Contenu principal</ColoredCard>
|
||||
<ColoredCard color="purple">Contenu violet</ColoredCard>
|
||||
<ColoredCard color="yellow">Contenu jaune</ColoredCard>
|
||||
```
|
||||
|
||||
## Couleurs disponibles
|
||||
|
||||
### Couleurs principales
|
||||
- `--background` : Arrière-plan principal
|
||||
- `--foreground` : Texte principal
|
||||
- `--card` : Arrière-plan des cartes
|
||||
- `--card-hover` : État hover des cartes
|
||||
- `--border` : Couleur des bordures
|
||||
- `--input` : Arrière-plan des inputs
|
||||
|
||||
### Couleurs sémantiques
|
||||
- `--primary` : Couleur principale (cyan)
|
||||
- `--success` : Succès (vert)
|
||||
- `--destructive` : Erreur/danger (rouge)
|
||||
- `--accent` : Accent (orange/amber)
|
||||
- `--muted` : Texte atténué
|
||||
- `--muted-foreground` : Texte secondaire
|
||||
|
||||
### Couleurs étendues
|
||||
- `--purple` : Violet
|
||||
- `--yellow` : Jaune
|
||||
- `--green` : Vert
|
||||
- `--blue` : Bleu
|
||||
- `--gray` : Gris
|
||||
- `--gray-light` : Gris clair
|
||||
|
||||
## Patterns de couleurs
|
||||
|
||||
### Messages d'état
|
||||
```typescript
|
||||
const { patterns } = useDesignTokens();
|
||||
|
||||
// Utilisation directe
|
||||
<div style={patterns.success}>Message de succès</div>
|
||||
<div style={patterns.error}>Message d'erreur</div>
|
||||
<div style={patterns.warning}>Message d'avertissement</div>
|
||||
```
|
||||
|
||||
### Opacités courantes
|
||||
```typescript
|
||||
const { opacity } = useDesignTokens();
|
||||
|
||||
// Opacités prédéfinies
|
||||
opacity.subtle // 5% - très subtil
|
||||
opacity.light // 10% - léger
|
||||
opacity.medium // 20% - moyen
|
||||
opacity.strong // 30% - fort
|
||||
opacity.solid // 80% - presque opaque
|
||||
```
|
||||
|
||||
## Bonnes pratiques
|
||||
|
||||
### ✅ Recommandé
|
||||
```tsx
|
||||
// Utiliser les design tokens
|
||||
const { colors, styles } = useDesignTokens();
|
||||
|
||||
<div style={{ color: colors.primary }}>
|
||||
<div style={styles.successMessage}>
|
||||
|
||||
// Utiliser les composants utilitaires
|
||||
<StatusMessage type="success">Succès</StatusMessage>
|
||||
<ColoredCard color="primary">Contenu</ColoredCard>
|
||||
```
|
||||
|
||||
### ❌ À éviter
|
||||
```tsx
|
||||
// Couleurs hardcodées
|
||||
<div style={{ color: '#0891b2' }}>
|
||||
<div className="text-blue-600">
|
||||
|
||||
// Classes Tailwind dark:
|
||||
<div className="bg-white dark:bg-gray-800">
|
||||
```
|
||||
|
||||
## Migration des composants existants
|
||||
|
||||
### Avant (avec classes Tailwind)
|
||||
```tsx
|
||||
<div className="bg-green-50 border border-green-200 text-green-800 dark:bg-green-900/20 dark:border-green-800 dark:text-green-200">
|
||||
✅ Succès
|
||||
</div>
|
||||
```
|
||||
|
||||
### Après (avec design tokens)
|
||||
```tsx
|
||||
<StatusMessage type="success">
|
||||
Succès
|
||||
</StatusMessage>
|
||||
```
|
||||
|
||||
## Extensibilité
|
||||
|
||||
Le système est conçu pour supporter facilement :
|
||||
- **Nouveaux thèmes** : Ajouter dans `themeTokens`
|
||||
- **Nouveaux patterns** : Étendre `COLOR_PATTERNS`
|
||||
- **Nouvelles opacités** : Ajouter dans `OPACITY`
|
||||
- **Composants personnalisés** : Utiliser `useDesignTokens`
|
||||
|
||||
## Exemples d'usage
|
||||
|
||||
### Composant personnalisé
|
||||
```tsx
|
||||
import { useDesignTokens } from '@/hooks/useDesignTokens';
|
||||
|
||||
function CustomComponent() {
|
||||
const { colors, withOpacity } = useDesignTokens();
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: withOpacity(colors.primary, 0.1),
|
||||
borderColor: colors.primary,
|
||||
color: colors.primary
|
||||
}}
|
||||
>
|
||||
Contenu personnalisé
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Style conditionnel
|
||||
```tsx
|
||||
function ConditionalComponent({ isActive }: { isActive: boolean }) {
|
||||
const { colors } = useDesignTokens();
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: isActive ? colors.success : colors.mutedForeground
|
||||
}}
|
||||
>
|
||||
{isActive ? 'Actif' : 'Inactif'}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Ce système garantit la cohérence visuelle et facilite la maintenance des styles dans toute l'application.
|
||||
@@ -1,241 +0,0 @@
|
||||
/**
|
||||
* Design Tokens - Système de couleurs cohérent pour TowerControl
|
||||
*
|
||||
* Ce fichier définit tous les tokens de design utilisés dans l'application.
|
||||
* Il sert de source unique de vérité pour les couleurs et facilite la maintenance.
|
||||
*/
|
||||
|
||||
export type ColorToken = string;
|
||||
|
||||
export interface ColorPalette {
|
||||
// Couleurs principales
|
||||
background: ColorToken;
|
||||
foreground: ColorToken;
|
||||
|
||||
// Surfaces
|
||||
card: ColorToken;
|
||||
cardHover: ColorToken;
|
||||
cardColumn: ColorToken;
|
||||
|
||||
// Bordures et inputs
|
||||
border: ColorToken;
|
||||
input: ColorToken;
|
||||
|
||||
// Couleurs sémantiques
|
||||
primary: ColorToken;
|
||||
primaryForeground: ColorToken;
|
||||
muted: ColorToken;
|
||||
mutedForeground: ColorToken;
|
||||
|
||||
// Couleurs d'état
|
||||
destructive: ColorToken;
|
||||
success: ColorToken;
|
||||
accent: ColorToken;
|
||||
|
||||
// Couleurs étendues
|
||||
purple: ColorToken;
|
||||
yellow: ColorToken;
|
||||
green: ColorToken;
|
||||
blue: ColorToken;
|
||||
gray: ColorToken;
|
||||
grayLight: ColorToken;
|
||||
}
|
||||
|
||||
export interface ThemeTokens {
|
||||
light: ColorPalette;
|
||||
dark: ColorPalette;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokens de couleurs pour le thème clair
|
||||
*/
|
||||
export const lightTheme: ColorPalette = {
|
||||
// Couleurs principales
|
||||
background: '#f1f5f9', // slate-100
|
||||
foreground: '#0f172a', // slate-900
|
||||
|
||||
// Surfaces
|
||||
card: '#ffffff', // white
|
||||
cardHover: '#f8fafc', // slate-50
|
||||
cardColumn: '#f8fafc', // slate-50
|
||||
|
||||
// Bordures et inputs
|
||||
border: '#cbd5e1', // slate-300
|
||||
input: '#ffffff', // white
|
||||
|
||||
// Couleurs sémantiques
|
||||
primary: '#0891b2', // cyan-600
|
||||
primaryForeground: '#ffffff', // white
|
||||
muted: '#94a3b8', // slate-400
|
||||
mutedForeground: '#64748b', // slate-500
|
||||
|
||||
// Couleurs d'état
|
||||
destructive: '#dc2626', // red-600
|
||||
success: '#059669', // emerald-600
|
||||
accent: '#d97706', // amber-600
|
||||
|
||||
// Couleurs étendues
|
||||
purple: '#8b5cf6', // purple-500
|
||||
yellow: '#eab308', // yellow-500
|
||||
green: '#059669', // emerald-600
|
||||
blue: '#2563eb', // blue-600
|
||||
gray: '#6b7280', // gray-500
|
||||
grayLight: '#e5e7eb', // gray-200
|
||||
};
|
||||
|
||||
/**
|
||||
* Tokens de couleurs pour le thème sombre
|
||||
*/
|
||||
export const darkTheme: ColorPalette = {
|
||||
// Couleurs principales
|
||||
background: '#1e293b', // slate-800
|
||||
foreground: '#f1f5f9', // slate-100
|
||||
|
||||
// Surfaces
|
||||
card: '#334155', // slate-700
|
||||
cardHover: '#475569', // slate-600
|
||||
cardColumn: '#0f172a', // slate-900
|
||||
|
||||
// Bordures et inputs
|
||||
border: '#64748b', // slate-500
|
||||
input: '#334155', // slate-700
|
||||
|
||||
// Couleurs sémantiques
|
||||
primary: '#06b6d4', // cyan-500
|
||||
primaryForeground: '#f1f5f9', // slate-100
|
||||
muted: '#64748b', // slate-500
|
||||
mutedForeground: '#94a3b8', // slate-400
|
||||
|
||||
// Couleurs d'état
|
||||
destructive: '#ef4444', // red-500
|
||||
success: '#10b981', // emerald-500
|
||||
accent: '#f59e0b', // amber-500
|
||||
|
||||
// Couleurs étendues
|
||||
purple: '#8b5cf6', // purple-500
|
||||
yellow: '#eab308', // yellow-500
|
||||
green: '#10b981', // emerald-500
|
||||
blue: '#3b82f6', // blue-500
|
||||
gray: '#9ca3af', // gray-400
|
||||
grayLight: '#374151', // gray-700
|
||||
};
|
||||
|
||||
/**
|
||||
* Collection complète des tokens de thème
|
||||
*/
|
||||
export const themeTokens: ThemeTokens = {
|
||||
light: lightTheme,
|
||||
dark: darkTheme,
|
||||
};
|
||||
|
||||
/**
|
||||
* Utilitaires pour les tokens de couleur
|
||||
*/
|
||||
export class DesignTokenUtils {
|
||||
/**
|
||||
* Génère une couleur avec transparence
|
||||
*/
|
||||
static withOpacity(color: ColorToken, opacity: number): string {
|
||||
return `color-mix(in srgb, ${color} ${opacity * 100}%, transparent)`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère une couleur de bordure avec transparence
|
||||
*/
|
||||
static borderWithOpacity(color: ColorToken, opacity: number, baseBorder: ColorToken): string {
|
||||
return `color-mix(in srgb, ${color} ${opacity * 100}%, ${baseBorder})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un background avec transparence
|
||||
*/
|
||||
static backgroundWithOpacity(color: ColorToken, opacity: number): string {
|
||||
return `color-mix(in srgb, ${color} ${opacity * 100}%, transparent)`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient les tokens pour un thème donné
|
||||
*/
|
||||
static getTokens(theme: 'light' | 'dark'): ColorPalette {
|
||||
return themeTokens[theme];
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère les CSS Variables pour un thème
|
||||
*/
|
||||
static generateCSSVariables(theme: 'light' | 'dark'): Record<string, string> {
|
||||
const tokens = this.getTokens(theme);
|
||||
return {
|
||||
'--background': tokens.background,
|
||||
'--foreground': tokens.foreground,
|
||||
'--card': tokens.card,
|
||||
'--card-hover': tokens.cardHover,
|
||||
'--card-column': tokens.cardColumn,
|
||||
'--border': tokens.border,
|
||||
'--input': tokens.input,
|
||||
'--primary': tokens.primary,
|
||||
'--primary-foreground': tokens.primaryForeground,
|
||||
'--muted': tokens.muted,
|
||||
'--muted-foreground': tokens.mutedForeground,
|
||||
'--destructive': tokens.destructive,
|
||||
'--success': tokens.success,
|
||||
'--accent': tokens.accent,
|
||||
'--purple': tokens.purple,
|
||||
'--yellow': tokens.yellow,
|
||||
'--green': tokens.green,
|
||||
'--blue': tokens.blue,
|
||||
'--gray': tokens.gray,
|
||||
'--gray-light': tokens.grayLight,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constantes pour les opacités courantes
|
||||
*/
|
||||
export const OPACITY = {
|
||||
subtle: 0.05, // 5% - très subtil
|
||||
light: 0.1, // 10% - léger
|
||||
medium: 0.2, // 20% - moyen
|
||||
strong: 0.3, // 30% - fort
|
||||
solid: 0.8, // 80% - presque opaque
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Patterns de couleurs prédéfinis pour les composants
|
||||
*/
|
||||
export const COLOR_PATTERNS = {
|
||||
// Messages d'état
|
||||
success: {
|
||||
text: 'var(--success)',
|
||||
background: DesignTokenUtils.withOpacity('var(--success)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--success)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
error: {
|
||||
text: 'var(--destructive)',
|
||||
background: DesignTokenUtils.withOpacity('var(--destructive)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--destructive)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
warning: {
|
||||
text: 'var(--accent)',
|
||||
background: DesignTokenUtils.withOpacity('var(--accent)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--accent)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
|
||||
// Cards colorées
|
||||
primary: {
|
||||
text: 'var(--primary)',
|
||||
background: DesignTokenUtils.withOpacity('var(--primary)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--primary)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
purple: {
|
||||
text: 'var(--purple)',
|
||||
background: DesignTokenUtils.withOpacity('var(--purple)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--purple)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
yellow: {
|
||||
text: 'var(--yellow)',
|
||||
background: DesignTokenUtils.withOpacity('var(--yellow)', OPACITY.light),
|
||||
border: DesignTokenUtils.borderWithOpacity('var(--yellow)', OPACITY.medium, 'var(--border)'),
|
||||
},
|
||||
} as const;
|
||||
Reference in New Issue
Block a user