Files
OpenNoodl/dev-docs/tasks/phase-9-styles-overhaul/STYLE-002-element-configs/PLAN-DATTAQUE.md
Tara West 5c8aa4af2f feat(styles): Complete MVP2 - ElementConfigs system with node integration
Implements MVP2 of the ElementConfigs system, applying default styles to newly created nodes.

 Completed:
- ElementConfigRegistry with singleton pattern
- 5 node configs (Button, Text, Group, TextInput, Image)
- 28 total style variants defined
- Integration in router.tsx for app startup
- Unit tests for registry

 Validated:
- Button node: 100% defaults applied correctly
- Text node: Partial defaults applied (fontSize, color work)
- System initializes successfully at startup

⚠️ Known Issues:
- Text lineHeight and fontWeight not fully applied (likely interaction with legacy text style system)
- Requires cache clear (npm run clean:all) for changes to take effect

📝 Documentation:
- MVP2 validation report with test results
- Detailed changelog of implementation steps

🚀 Next: MVP3 will add variant selector UI in Property Panel

Ref: STYLE-002 Phase 9
2026-01-15 22:45:34 +01:00

17 KiB

STYLE-002: Element Configs & Variants - Plan d'Attaque

Date: 15 janvier 2026
Estimé Total: 16-20 heures
Stratégie: Approche MVP progressive (comme STYLE-001)


📊 Vue d'Ensemble

STYLE-002 crée un système de configuration d'éléments avec variantes pour les nodes visuels de Noodl. Au lieu de tout faire d'un coup (risque de dépassement de contexte), nous allons procéder par MVPs successifs.

Dépendances:

  • STYLE-001 MVP (complété) - système de tokens disponible

🎯 Stratégie: 3 MVPs Progressifs

MVP 1: Config System + Text Bug Fix (6-8h)

Objectif: Infrastructure de base + correction bug critique
Livrables: Registry fonctionnel, 2 configs (Button, Text), bug Text corrigé

MVP 2: Node Integration + Defaults (5-7h)

Objectif: Application automatique des configs à la création
Livrables: Nodes créés avec styles par défaut, 3 nodes supplémentaires

MVP 3: Variants + UI (5-6h)

Objectif: Système de variantes avec UI de sélection
Livrables: Changement de variantes via property panel

Custom Variants: Phase STYLE-002 Full (post-MVP)


📋 MVP 1: Config System + Text Bug Fix

Objectifs

  • Infrastructure ElementConfig fonctionnelle
  • Registry pour enregistrer/récupérer configs
  • 2 configs complets: Button, Text
  • Bug Fix: Corriger le problème de sizing du Text element

Sous-Tâches

1A. Types & Interfaces (1h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/
├── ElementConfigTypes.ts
└── index.ts

Contenu:

  • Interface ElementConfig
  • Interface VariantConfig
  • Interface StateConfig
  • Type ElementConfigRegistry

Tester: Les types compilent sans erreur


1B. Registry Implementation (1.5h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/
├── ElementConfigRegistry.ts
└── index.ts (update)

Fonctionnalités:

  • register(config) - enregistrer une config
  • get(nodeType) - récupérer une config
  • getVariants(nodeType) - lister les variantes
  • applyDefaults(node) - appliquer les defaults
  • applyVariant(node, variantName) - appliquer une variante

Tester: Unit tests basiques (register/get)


1C. ButtonConfig Implementation (1.5h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
├── ButtonConfig.ts
└── index.ts

Contenu:

  • Defaults complets (padding, typography, border, etc.)
  • 6 variantes: primary, secondary, outline, ghost, destructive, link
  • States: hover, active, disabled pour chaque variante
  • Sizes: sm, md, lg, xl

Tester: Config enregistrée dans le registry, récupérable


1D. TextConfig Implementation (1h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
├── TextConfig.ts
└── index.ts (update)

Contenu:

  • Defaults avec bug fix: width: 'auto', flexShrink: 1, minWidth: 0
  • 10 variantes: body, heading-1 à heading-6, muted, label, small, code
  • Pas de states pour Text (pas interactif)

Tester: Config enregistrée, defaults incluent les fix flex


1E. Text Element Bug Fix (2h)

Fichiers à modifier:

packages/noodl-viewer-react/src/nodes/basic/Text.jsx
packages/noodl-runtime/src/nodes/basic/text.js (si existe)

Changements:

// AVANT (bug)
const defaultStyle = {
  width: '100%',
  height: 'auto',
};

// APRÈS (fix)
const defaultStyle = {
  width: 'auto',      // Changé de '100%'
  height: 'auto',
  flexShrink: 1,      // Nouveau
  flexGrow: 0,        // Nouveau
  minWidth: 0,        // Nouveau
};

Tester:

  1. Créer un Group avec flexDirection: row
  2. Ajouter 2 Text elements comme enfants
  3. Vérifier que les deux sont visibles côte à côte
  4. Avant fix: Le 2e déborde à droite
  5. Après fix: Les deux partagent l'espace

MVP 1 - Résumé

  • Types TypeScript définis
  • Registry implémenté et testé
  • ButtonConfig complet avec 6 variantes
  • TextConfig complet avec 10 variantes
  • Bug Text sizing corrigé et testé

Livrable: Infrastructure ElementConfig + 2 configs + bug fix critique


📋 MVP 2: Node Integration + Defaults

Objectifs

  • Intégrer le système de configs dans la création de nodes
  • Appliquer automatiquement les defaults à la création
  • Ajouter 3 configs supplémentaires: Group, TextInput, Image

Sous-Tâches

2A. Hook Node Creation (2h)

Fichiers à modifier:

packages/noodl-editor/src/editor/src/models/
├── NodeModel.ts
├── NodeGraphModel.ts
└── nodelibrary.ts (ou fichier de création de node)

Fonctionnalités:

  • Détecter la création d'un nouveau node
  • Récupérer la config via ElementConfigRegistry.get(nodeType)
  • Appliquer les defaults via ElementConfigRegistry.applyDefaults(node)
  • Stocker la variante par défaut dans node.parameters

Tester: Créer un Button, vérifier que padding/colors sont appliqués


2B. GroupConfig Implementation (1h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
├── GroupConfig.ts
└── index.ts (update)

Contenu:

  • Defaults: display: flex, flexDirection: column
  • 7 variantes: default, card, section, inset, flex-row, flex-col, centered

Tester: Créer un Group, vérifier defaults appliqués


2C. TextInputConfig Implementation (1h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
├── TextInputConfig.ts
└── index.ts (update)

Contenu:

  • Defaults: padding, border, typography
  • 2 variantes: default, error
  • States: focus, disabled, placeholder

Tester: Créer un TextInput, vérifier styling


2D. ImageConfig Implementation (0.5h)

Fichiers à créer:

packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
├── ImageConfig.ts
└── index.ts (update)

Contenu:

  • Defaults: width: auto, height: auto, objectFit: cover
  • 3 variantes: default, rounded, circle

Tester: Créer une Image, vérifier defaults


2E. Integration Testing (1h)

Tests manuels:

  1. Créer un nouveau projet vide
  2. Drag & drop chaque type de node (Button, Text, Group, TextInput, Image)
  3. Vérifier que chaque node a les bonnes propriétés par défaut
  4. Inspecter node.parameters pour vérifier _variant
  5. Vérifier dans le preview que les styles sont appliqués

Tests unitaires:

  • Test de création de node avec config
  • Test d'application des defaults
  • Test de stockage de la variante par défaut

MVP 2 - Résumé

  • Hook de création de node implémenté
  • Defaults appliqués automatiquement
  • 3 nouvelles configs: Group, TextInput, Image
  • Tests d'intégration passent

Livrable: Nodes créés avec styles par défaut automatiquement


📋 MVP 3: Variants + UI

Objectifs

  • Permettre le changement de variante via property panel
  • Créer l'UI VariantSelector
  • Appliquer la variante sélectionnée au node

Sous-Tâches

3A. VariantSelector Component (2h)

Fichiers à créer:

packages/noodl-core-ui/src/components/inputs/VariantSelector/
├── VariantSelector.tsx
├── VariantSelector.module.scss
├── VariantSelector.stories.tsx
└── index.ts

UI Structure:

┌──────────────────────────────┐
│ Variant: [Primary ▼]         │
│          ┌────────────────┐  │
│          │ ● Primary      │  │
│          │   Secondary    │  │
│          │   Outline      │  │
│          │   Ghost        │  │
│          │   Destructive  │  │
│          │   Link         │  │
│          └────────────────┘  │
└──────────────────────────────┘

Props:

interface VariantSelectorProps {
  nodeType: string;
  currentVariant: string;
  onChange: (variant: string) => void;
}

Tester: Storybook stories pour différents node types


3B. Property Panel Integration (1.5h)

Fichiers à modifier/créer:

packages/noodl-editor/src/editor/src/views/panels/propertyeditor/
├── PropertyEditor.tsx (ou fichier principal)
├── VariantSection.tsx (nouveau)
└── sections/ (dossier pour les sections)

Fonctionnalités:

  • Détecter si le node sélectionné a une config
  • Si oui, afficher la section "Variant" en haut du property panel
  • Utiliser VariantSelector pour changer la variante
  • Appeler ElementConfigRegistry.applyVariant(node, variantName) au changement

Tester: Sélectionner un Button, changer la variante, voir le changement


3C. Variant Application in Viewer (1.5h)

Fichiers à modifier:

packages/noodl-viewer-react/src/
├── nodes/controls/Button.jsx
├── nodes/basic/Text.jsx
├── nodes/std-library/group.js
└── react-component-node.js (helper pour résolution de variantes)

Fonctionnalités:

  • Lire node.parameters._variant ou node.variant
  • Récupérer la config de la variante
  • Appliquer les styles de la variante au composant
  • Merger avec les propriétés custom de l'utilisateur (user overrides)

Ordre de priorité des styles:

  1. Defaults de la config
  2. Styles de la variante
  3. Propriétés définies par l'utilisateur (highest priority)

Tester: Changer la variante dans le property panel, voir le preview se mettre à jour


MVP 3 - Résumé

  • VariantSelector UI créé et testé dans Storybook
  • Property panel affiche les variantes disponibles
  • Changement de variante met à jour le node
  • Preview reflète la variante sélectionnée

Livrable: Système de variantes fonctionnel avec UI


🚀 Ordre d'Exécution Recommandé

Session 1: MVP 1 - Infrastructure (3-4h)

# 1. Types & Registry
- Créer ElementConfigTypes.ts
- Créer ElementConfigRegistry.ts
- Tests unitaires basiques

# 2. Première Config (Button)
- Créer ButtonConfig.ts
- Enregistrer dans le registry
- Tester la récupération

Point de contrôle: Registry fonctionne, ButtonConfig enregistré


Session 2: MVP 1 - Configs + Bug Fix (3-4h)

# 3. Deuxième Config (Text)
- Créer TextConfig.ts
- Inclure les fix flex dans defaults

# 4. Bug Fix Text Element
- Modifier Text.jsx (viewer)
- Tester avec 2 Text en row layout

Point de contrôle: 2 configs, bug Text corrigé


Session 3: MVP 2 - Integration (3-4h)

# 5. Hook Node Creation
- Modifier NodeModel/NodeGraphModel
- Appliquer defaults à la création

# 6. Configs Supplémentaires
- GroupConfig.ts
- TextInputConfig.ts
- ImageConfig.ts

Point de contrôle: Nodes créés avec defaults automatiquement


Session 4: MVP 3 - Variants UI (2-3h)

# 7. VariantSelector Component
- Créer le composant UI
- Storybook stories

Point de contrôle: UI testée dans Storybook


Session 5: MVP 3 - Integration (2-3h)

# 8. Property Panel Integration
- Ajouter VariantSection
- Connecter VariantSelector

# 9. Viewer Integration
- Appliquer variantes dans les nodes
- Tester le changement en temps réel

Point de contrôle: Système complet fonctionnel


Checklist Finale de Validation

MVP 1: Config System

  • ElementConfigTypes.ts compilé sans erreur
  • ElementConfigRegistry implémenté
  • ButtonConfig avec 6 variantes + 4 sizes
  • TextConfig avec 10 variantes
  • Bug Text sizing corrigé (2 Text en row partagent l'espace)

MVP 2: Node Integration

  • Hook node creation fonctionne
  • Defaults appliqués automatiquement
  • GroupConfig avec 7 variantes
  • TextInputConfig avec 2 variantes + states
  • ImageConfig avec 3 variantes
  • Test: Créer chaque type de node → styles par défaut visibles

MVP 3: Variants UI

  • VariantSelector UI créé
  • Storybook stories fonctionnelles
  • Property panel affiche la section Variant
  • Changement de variante met à jour le node
  • Preview reflète la variante en temps réel
  • User overrides ont priorité sur variantes

Qualité & Documentation

  • Tous les fichiers ont des commentaires JSDoc
  • Code suit les standards TypeScript (.clinerules)
  • Pas de TSFixme ajoutés
  • Tests unitaires pour le registry
  • CHANGELOG.md créé avec les changements
  • README.md mis à jour si nécessaire

🔧 Points Techniques Importants

1. Résolution de Tokens dans les Variantes

Les configs utilisent var(--token-name). Le runtime doit:

  • Résoudre ces références via CSS (fonctionnera automatiquement)
  • Pas besoin de parsing spécial, le browser gère var()

2. Priorité des Styles

Defaults (lowest)
  ↓
Variant Styles
  ↓
User Overrides (highest)

Implémentation:

const finalStyles = {
  ...config.defaults,
  ...variant.styles,
  ...node.userStyles // Always win
};

3. Storing Variant Selection

Stocker dans node.parameters:

node.parameters._variant = 'primary';
// OU
node.variant = 'primary';

Préfixe _ pour indiquer que c'est une propriété système, pas utilisateur.

4. States (Hover, Active, etc.)

Pour MVP 3, les states sont:

  • Définis dans la config
  • Appliqués via React state hooks (useState pour hover/active)
  • Mergés avec les styles de base

Exemple:

const [isHovered, setIsHovered] = useState(false);

const styles = {
  ...baseStyles,
  ...(isHovered && variant.states?.hover)
};

return (
  <button
    style={styles}
    onMouseEnter={() => setIsHovered(true)}
    onMouseLeave={() => setIsHovered(false)}
  >
    {children}
  </button>
);

🚧 Hors Scope du MVP

Ces features sont prévues pour STYLE-002 Full (post-MVP):

  • Custom variant creation (UI "Save as Variant")
  • Custom variant storage (project/global)
  • Variant import/export
  • Variant preview thumbnails in selector
  • Size presets UI (sm, md, lg, xl)
  • Responsive variants (breakpoint-specific)

📝 Recommandations pour l'Implémentation

Approche Progressive

Ne PAS tout faire d'un coup - Risque de dépassement de contexte API.

  1. Session 1: Types + Registry + ButtonConfig (3-4 fichiers)
  2. Session 2: TextConfig + Bug Fix (2 fichiers)
  3. Session 3: Node Integration + 3 Configs (5 fichiers)
  4. Session 4: VariantSelector UI (4 fichiers)
  5. Session 5: Property Panel + Viewer Integration (5 fichiers)

Commits Fréquents

Commit après chaque sous-tâche complétée:

git commit -m "feat(element-configs): Add ElementConfigTypes and Registry"
git commit -m "feat(element-configs): Add ButtonConfig with 6 variants"
git commit -m "fix(text): Fix Text element flex sizing issue"

Tests Continus

Tester après chaque sous-tâche, pas à la fin. Si quelque chose ne marche pas, c'est plus facile à debugger.


📅 Timeline Estimée

Session Durée Tâches Livrable
1 3-4h Types + Registry + ButtonConfig Infrastructure
2 3-4h TextConfig + Bug Fix 2 configs + fix
3 3-4h Node Integration + 3 Configs Auto-defaults
4 2-3h VariantSelector UI UI component
5 2-3h Property Panel + Viewer MVP complet

Total: 13-18 heures (dans l'estimé initial 16-20h)


🎯 Critères de Succès

MVP 1 Success:

  • Registry fonctionne
  • 2 configs (Button, Text) enregistrés
  • Bug Text corrigé
  • Tests manuels passent

MVP 2 Success:

  • Drag & drop d'un Button/Text/Group/TextInput/Image
  • Styles par défaut visibles immédiatement dans le preview
  • Pas d'erreurs console

MVP 3 Success:

  • Property panel affiche "Variant" pour nodes configurés
  • Changer la variante met à jour le preview en temps réel
  • User peut override les styles de variante

Validation Finale:

  • Créer un nouveau projet
  • Ajouter 1 Button, 1 Text, 1 Group
  • Changer leurs variantes
  • Vérifier que le preview reflète les changements
  • STYLE-002 MVP est complet

📚 Ressources & Références

Fichiers Clés à Étudier

# Pour comprendre node creation:
packages/noodl-editor/src/editor/src/models/NodeModel.ts
packages/noodl-editor/src/editor/src/models/NodeGraphModel.ts

# Pour comprendre property panel:
packages/noodl-editor/src/editor/src/views/panels/propertyeditor/

# Pour comprendre les nodes viewer:
packages/noodl-viewer-react/src/nodes/controls/Button.jsx
packages/noodl-viewer-react/src/nodes/basic/Text.jsx

# Pour les tokens (déjà implémenté):
packages/noodl-editor/src/editor/src/models/StyleTokens/

Patterns à Suivre

  • EventDispatcher: Utiliser useEventListener hook (pas direct .on())
  • TypeScript: Pas de TSFixme, types explicites
  • Commits: Format conventionnel (feat:, fix:, refactor:)
  • Comments: En anglais, expliquer le "why", pas le "what"

Créé le: 15 janvier 2026
Prochaine étape: Session 1 - Types + Registry + ButtonConfig


Prêt à démarrer quand vous voulez ! 🚀