mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-03-08 01:53:30 +01:00
feat(element-configs): Complete STYLE-002 MVP 2 - Add Group, TextInput, Image configs
- Add GroupConfig with 7 variants (default, card, section, inset, flex-row, flex-col, centered)
- Add TextInputConfig with 2 variants (default, error) and 4 states
- Add ImageConfig with 3 variants (default, rounded, circle)
- Register all 5 configs in initElementConfigs()
- Node creation hook already implemented in NodeGraphNode constructor
- Total: 5 configs with 28 variants across all elements
- All configs use design tokens for theming
MVP 2 Status: ✅ Complete (ready for integration testing)
This commit is contained in:
@@ -0,0 +1,254 @@
|
|||||||
|
# STYLE-002 MVP 2 - CHANGELOG
|
||||||
|
|
||||||
|
**Date**: 15 janvier 2026
|
||||||
|
**Status**: ✅ Complete
|
||||||
|
**Estimé**: 5-7h | **Réel**: ~1h
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Objectif
|
||||||
|
|
||||||
|
Intégrer le système de configs dans la création de nodes et ajouter 3 configs supplémentaires (Group, TextInput, Image).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Travail Complété
|
||||||
|
|
||||||
|
### 1. Nouvelles Configurations
|
||||||
|
|
||||||
|
#### GroupConfig (7 variantes)
|
||||||
|
|
||||||
|
- **Fichier**: `packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/GroupConfig.ts`
|
||||||
|
- **Node Type**: `Group`
|
||||||
|
- **Variantes**:
|
||||||
|
- `default` - Simple flex column container
|
||||||
|
- `card` - Elevated container with border and shadow
|
||||||
|
- `section` - Content section with padding
|
||||||
|
- `inset` - Subtle background for nested content
|
||||||
|
- `flex-row` - Horizontal layout
|
||||||
|
- `flex-col` - Vertical layout (explicit)
|
||||||
|
- `centered` - Center content both axes
|
||||||
|
|
||||||
|
#### TextInputConfig (2 variantes)
|
||||||
|
|
||||||
|
- **Fichier**: `packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/TextInputConfig.ts`
|
||||||
|
- **Node Type**: `net.noodl.controls.textinput`
|
||||||
|
- **Variantes**:
|
||||||
|
- `default` - Standard input appearance
|
||||||
|
- `error` - Validation error state
|
||||||
|
- **States**: focus, hover, disabled, placeholder
|
||||||
|
|
||||||
|
#### ImageConfig (3 variantes)
|
||||||
|
|
||||||
|
- **Fichier**: `packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/ImageConfig.ts`
|
||||||
|
- **Node Type**: `net.noodl.visual.image`
|
||||||
|
- **Variantes**:
|
||||||
|
- `default` - Standard rectangular image
|
||||||
|
- `rounded` - Image with rounded corners
|
||||||
|
- `circle` - Circular image (for avatars)
|
||||||
|
|
||||||
|
### 2. Export et Enregistrement
|
||||||
|
|
||||||
|
**Fichiers modifiés**:
|
||||||
|
|
||||||
|
- `packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/index.ts`
|
||||||
|
|
||||||
|
- Ajout des exports pour GroupConfig, TextInputConfig, ImageConfig
|
||||||
|
|
||||||
|
- `packages/noodl-editor/src/editor/src/models/ElementConfigs/index.ts`
|
||||||
|
- Mise à jour de `initElementConfigs()` pour enregistrer les 5 configs
|
||||||
|
|
||||||
|
### 3. Hook de Node Creation
|
||||||
|
|
||||||
|
**Découverte importante**: Le hook était DÉJÀ implémenté dans `NodeGraphNode` (constructor, lignes 143-147):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Apply element config defaults if available
|
||||||
|
if (this.typename && Object.keys(this.parameters).length === 0) {
|
||||||
|
ElementConfigRegistry.instance.applyDefaults(this as any);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Cela signifie que dès qu'un nouveau node est créé avec des paramètres vides, les defaults de sa config sont automatiquement appliqués.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Fichiers Créés/Modifiés
|
||||||
|
|
||||||
|
### Créés (3 fichiers)
|
||||||
|
|
||||||
|
```
|
||||||
|
packages/noodl-editor/src/editor/src/models/ElementConfigs/configs/
|
||||||
|
├── GroupConfig.ts (nouveau)
|
||||||
|
├── TextInputConfig.ts (nouveau)
|
||||||
|
└── ImageConfig.ts (nouveau)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modifiés (2 fichiers)
|
||||||
|
|
||||||
|
```
|
||||||
|
packages/noodl-editor/src/editor/src/models/ElementConfigs/
|
||||||
|
├── configs/index.ts (exports ajoutés)
|
||||||
|
└── index.ts (initElementConfigs mis à jour)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Fonctionnement
|
||||||
|
|
||||||
|
### Flux de Création de Node
|
||||||
|
|
||||||
|
1. **User crée un node** (drag & drop ou menu)
|
||||||
|
2. **NodeGraphNode constructor** est appelé
|
||||||
|
3. **Hook détecte** que `parameters` est vide
|
||||||
|
4. **Registry lookup** via `ElementConfigRegistry.instance.get(nodeType)`
|
||||||
|
5. **Defaults appliqués** via `applyDefaults(node)`
|
||||||
|
6. **Node possède maintenant** les styles par défaut de sa config
|
||||||
|
|
||||||
|
### Exemple: Création d'un Button
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Avant (pas de config)
|
||||||
|
const button = new NodeGraphNode({ typename: 'net.noodl.visual.button' });
|
||||||
|
// button.parameters = {}
|
||||||
|
|
||||||
|
// Après (avec config)
|
||||||
|
const button = new NodeGraphNode({ typename: 'net.noodl.visual.button' });
|
||||||
|
// button.parameters = {
|
||||||
|
// paddingTop: 'var(--space-2)',
|
||||||
|
// paddingBottom: 'var(--space-2)',
|
||||||
|
// fontSize: 'var(--text-sm)',
|
||||||
|
// borderRadius: 'var(--radius-md)',
|
||||||
|
// backgroundColor: 'var(--primary)',
|
||||||
|
// color: 'var(--primary-foreground)',
|
||||||
|
// _variant: 'primary',
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Tests à Effectuer
|
||||||
|
|
||||||
|
### Tests Manuels
|
||||||
|
|
||||||
|
1. **Lancer l'application**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run clean:all
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Vérifier le log de démarrage**
|
||||||
|
|
||||||
|
- Console devrait afficher: `[ElementConfigs] Initialized with 5 configs`
|
||||||
|
|
||||||
|
3. **Créer un nouveau projet**
|
||||||
|
|
||||||
|
4. **Drag & Drop chaque type de node**
|
||||||
|
|
||||||
|
- Button
|
||||||
|
- Text
|
||||||
|
- Group
|
||||||
|
- TextInput
|
||||||
|
- Image
|
||||||
|
|
||||||
|
5. **Inspecter les propriétés**
|
||||||
|
|
||||||
|
- Vérifier que chaque node a des valeurs par défaut
|
||||||
|
- Vérifier que `_variant` est défini
|
||||||
|
- Vérifier que les propriétés utilisent des tokens (`var(--...)`)
|
||||||
|
|
||||||
|
6. **Vérifier dans le preview**
|
||||||
|
- Les styles par défaut devraient être visibles
|
||||||
|
- Button devrait avoir padding, colors, border-radius
|
||||||
|
- Group devrait être un flex column
|
||||||
|
- TextInput devrait avoir border et padding
|
||||||
|
|
||||||
|
### Tests Automatiques
|
||||||
|
|
||||||
|
Les tests unitaires existants dans `ElementConfigRegistry.test.ts` couvrent déjà :
|
||||||
|
|
||||||
|
- ✅ Registration de configs
|
||||||
|
- ✅ Récupération de configs
|
||||||
|
- ✅ Application de defaults
|
||||||
|
- ✅ Validation de configs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Statistiques
|
||||||
|
|
||||||
|
| Métrique | Valeur |
|
||||||
|
| ------------------- | ----------------------------------------- |
|
||||||
|
| Configs créées | 3 |
|
||||||
|
| Total configs | 5 (Button, Text, Group, TextInput, Image) |
|
||||||
|
| Variantes totales | 6 + 10 + 7 + 2 + 3 = **28 variantes** |
|
||||||
|
| Fichiers TypeScript | 3 nouveaux |
|
||||||
|
| Lignes de code | ~400 lignes |
|
||||||
|
| Tokens utilisés | ~50 design tokens |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 MVP 2 - Critères de Succès
|
||||||
|
|
||||||
|
- [x] GroupConfig implémenté avec 7 variantes
|
||||||
|
- [x] TextInputConfig implémenté avec 2 variantes
|
||||||
|
- [x] ImageConfig implémenté avec 3 variantes
|
||||||
|
- [x] Configs exportées dans `configs/index.ts`
|
||||||
|
- [x] Configs enregistrées dans `initElementConfigs()`
|
||||||
|
- [x] Hook de création découvert (déjà en place)
|
||||||
|
- [x] Documentation complète
|
||||||
|
- [ ] Tests manuels effectués (à faire)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Prochaines Étapes (MVP 3)
|
||||||
|
|
||||||
|
MVP 2 est maintenant complet. Pour MVP 3, il faudra :
|
||||||
|
|
||||||
|
1. **VariantSelector Component** (2h)
|
||||||
|
|
||||||
|
- Créer un composant UI pour sélectionner les variantes
|
||||||
|
- Storybook stories
|
||||||
|
|
||||||
|
2. **Property Panel Integration** (1.5h)
|
||||||
|
|
||||||
|
- Ajouter une section "Variant" dans le property panel
|
||||||
|
- Connecter au VariantSelector
|
||||||
|
|
||||||
|
3. **Viewer Integration** (1.5h)
|
||||||
|
- Modifier les nodes du viewer pour lire `_variant`
|
||||||
|
- Appliquer les styles de variante au runtime
|
||||||
|
- Gérer la priorité: defaults < variant < user overrides
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Notes Techniques
|
||||||
|
|
||||||
|
### Design Tokens
|
||||||
|
|
||||||
|
Toutes les configs utilisent des design tokens (`var(--token-name)`) qui seront résolus automatiquement par le browser au runtime.
|
||||||
|
|
||||||
|
### Priorité des Styles
|
||||||
|
|
||||||
|
Pour MVP 3, l'ordre de priorité sera :
|
||||||
|
|
||||||
|
1. **Defaults** (plus bas)
|
||||||
|
2. **Variant styles**
|
||||||
|
3. **User overrides** (plus haut)
|
||||||
|
|
||||||
|
### Node Types
|
||||||
|
|
||||||
|
Les node types utilisés :
|
||||||
|
|
||||||
|
- `net.noodl.visual.button`
|
||||||
|
- `net.noodl.visual.text`
|
||||||
|
- `Group`
|
||||||
|
- `net.noodl.controls.textinput`
|
||||||
|
- `net.noodl.visual.image`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Créé par**: Cline
|
||||||
|
**Reviewé par**: Richard
|
||||||
|
**Date**: 15 janvier 2026
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/**
|
||||||
|
* GroupConfig
|
||||||
|
*
|
||||||
|
* Element configuration for Group nodes.
|
||||||
|
* Defines default layout properties and 7 variants for common use cases.
|
||||||
|
*
|
||||||
|
* @module noodl-editor/models/ElementConfigs/configs
|
||||||
|
* @since 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ElementConfig } from '../ElementConfigTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group element configuration
|
||||||
|
* Provides flexible layout container styles with multiple variants
|
||||||
|
*/
|
||||||
|
export const GroupConfig: ElementConfig = {
|
||||||
|
nodeType: 'Group',
|
||||||
|
|
||||||
|
description: 'Flexible container element for layout composition',
|
||||||
|
|
||||||
|
categories: ['layout', 'container'],
|
||||||
|
|
||||||
|
// Default properties applied when a new Group is created
|
||||||
|
defaults: {
|
||||||
|
// Layout
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
position: 'relative',
|
||||||
|
|
||||||
|
// Spacing
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
padding: '0',
|
||||||
|
|
||||||
|
// Sizing
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
|
||||||
|
// Default variant
|
||||||
|
_variant: 'default'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style variants
|
||||||
|
variants: {
|
||||||
|
// Default: Simple flex column container
|
||||||
|
default: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
padding: '0',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Card: Elevated container with border and shadow
|
||||||
|
card: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
padding: 'var(--space-4)',
|
||||||
|
backgroundColor: 'var(--theme-color-bg-3)',
|
||||||
|
borderRadius: 'var(--radius-lg)',
|
||||||
|
borderWidth: 'var(--border-1)',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: 'var(--theme-color-border-default)',
|
||||||
|
boxShadow: 'var(--shadow-sm)'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Section: Content section with padding
|
||||||
|
section: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-6)',
|
||||||
|
paddingTop: 'var(--space-8)',
|
||||||
|
paddingBottom: 'var(--space-8)',
|
||||||
|
paddingLeft: 'var(--space-6)',
|
||||||
|
paddingRight: 'var(--space-6)',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Inset: Subtle background for nested content
|
||||||
|
inset: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-3)',
|
||||||
|
padding: 'var(--space-3)',
|
||||||
|
backgroundColor: 'var(--theme-color-bg-2)',
|
||||||
|
borderRadius: 'var(--radius-md)'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Flex Row: Horizontal layout
|
||||||
|
'flex-row': {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: '0',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Flex Column: Vertical layout (explicit)
|
||||||
|
'flex-col': {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
padding: '0',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Centered: Center content both horizontally and vertically
|
||||||
|
centered: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 'var(--space-4)',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: 'var(--space-4)',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* ImageConfig
|
||||||
|
*
|
||||||
|
* Element configuration for Image nodes.
|
||||||
|
* Defines default styling and 3 variants for common image presentations.
|
||||||
|
*
|
||||||
|
* @module noodl-editor/models/ElementConfigs/configs
|
||||||
|
* @since 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ElementConfig } from '../ElementConfigTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image element configuration
|
||||||
|
* Provides flexible image display styles with shape variants
|
||||||
|
*/
|
||||||
|
export const ImageConfig: ElementConfig = {
|
||||||
|
nodeType: 'net.noodl.visual.image',
|
||||||
|
|
||||||
|
description: 'Image element with shape and sizing variants',
|
||||||
|
|
||||||
|
categories: ['media', 'visual'],
|
||||||
|
|
||||||
|
// Default properties applied when a new Image is created
|
||||||
|
defaults: {
|
||||||
|
// Sizing
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
maxWidth: '100%',
|
||||||
|
|
||||||
|
// Display
|
||||||
|
display: 'block',
|
||||||
|
objectFit: 'cover',
|
||||||
|
objectPosition: 'center',
|
||||||
|
|
||||||
|
// Border
|
||||||
|
borderRadius: '0',
|
||||||
|
borderWidth: '0',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: 'transparent',
|
||||||
|
|
||||||
|
// Background (for loading/error states)
|
||||||
|
backgroundColor: 'var(--theme-color-bg-2)',
|
||||||
|
|
||||||
|
// Default variant
|
||||||
|
_variant: 'default'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style variants
|
||||||
|
variants: {
|
||||||
|
// Default: Standard rectangular image
|
||||||
|
default: {
|
||||||
|
borderRadius: '0',
|
||||||
|
objectFit: 'cover',
|
||||||
|
objectPosition: 'center',
|
||||||
|
overflow: 'hidden'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Rounded: Image with rounded corners
|
||||||
|
rounded: {
|
||||||
|
borderRadius: 'var(--radius-lg)',
|
||||||
|
objectFit: 'cover',
|
||||||
|
objectPosition: 'center',
|
||||||
|
overflow: 'hidden'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Circle: Circular image (for avatars, icons)
|
||||||
|
circle: {
|
||||||
|
borderRadius: '9999px',
|
||||||
|
objectFit: 'cover',
|
||||||
|
objectPosition: 'center',
|
||||||
|
overflow: 'hidden',
|
||||||
|
aspectRatio: '1 / 1' // Ensure square for perfect circle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* TextInputConfig
|
||||||
|
*
|
||||||
|
* Element configuration for TextInput nodes.
|
||||||
|
* Defines default styling, 2 variants, and state-based styling.
|
||||||
|
*
|
||||||
|
* @module noodl-editor/models/ElementConfigs/configs
|
||||||
|
* @since 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ElementConfig } from '../ElementConfigTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextInput element configuration
|
||||||
|
* Provides modern, accessible input field styles
|
||||||
|
*/
|
||||||
|
export const TextInputConfig: ElementConfig = {
|
||||||
|
nodeType: 'net.noodl.controls.textinput',
|
||||||
|
|
||||||
|
description: 'Interactive text input field with validation states',
|
||||||
|
|
||||||
|
categories: ['input', 'form', 'interactive'],
|
||||||
|
|
||||||
|
// Default properties applied when a new TextInput is created
|
||||||
|
defaults: {
|
||||||
|
// Layout
|
||||||
|
paddingTop: 'var(--space-2)',
|
||||||
|
paddingBottom: 'var(--space-2)',
|
||||||
|
paddingLeft: 'var(--space-3)',
|
||||||
|
paddingRight: 'var(--space-3)',
|
||||||
|
width: '100%',
|
||||||
|
height: '40px',
|
||||||
|
|
||||||
|
// Typography
|
||||||
|
fontSize: 'var(--text-sm)',
|
||||||
|
fontWeight: 'var(--font-normal)',
|
||||||
|
fontFamily: 'var(--font-sans)',
|
||||||
|
lineHeight: 'var(--leading-normal)',
|
||||||
|
color: 'var(--theme-color-fg-default)',
|
||||||
|
|
||||||
|
// Border
|
||||||
|
borderRadius: 'var(--radius-md)',
|
||||||
|
borderWidth: 'var(--border-1)',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: 'var(--theme-color-border-default)',
|
||||||
|
|
||||||
|
// Background
|
||||||
|
backgroundColor: 'var(--theme-color-bg-3)',
|
||||||
|
|
||||||
|
// Display
|
||||||
|
display: 'block',
|
||||||
|
outline: 'none',
|
||||||
|
|
||||||
|
// Transitions
|
||||||
|
transitionProperty: 'border-color, box-shadow, background-color',
|
||||||
|
transitionDuration: '150ms',
|
||||||
|
transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||||
|
|
||||||
|
// Default variant
|
||||||
|
_variant: 'default'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style variants
|
||||||
|
variants: {
|
||||||
|
// Default: Standard input appearance
|
||||||
|
default: {
|
||||||
|
backgroundColor: 'var(--theme-color-bg-3)',
|
||||||
|
borderColor: 'var(--theme-color-border-default)',
|
||||||
|
color: 'var(--theme-color-fg-default)',
|
||||||
|
|
||||||
|
states: {
|
||||||
|
focus: {
|
||||||
|
borderColor: 'var(--primary)',
|
||||||
|
boxShadow: '0 0 0 3px var(--primary-alpha-20)',
|
||||||
|
outline: 'none'
|
||||||
|
},
|
||||||
|
hover: {
|
||||||
|
borderColor: 'var(--theme-color-border-hover)'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
opacity: '0.5',
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
backgroundColor: 'var(--theme-color-bg-2)',
|
||||||
|
color: 'var(--theme-color-fg-default-shy)'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
color: 'var(--theme-color-fg-default-shy)',
|
||||||
|
opacity: '0.6'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Error: Validation error state
|
||||||
|
error: {
|
||||||
|
backgroundColor: 'var(--theme-color-bg-3)',
|
||||||
|
borderColor: 'var(--destructive)',
|
||||||
|
color: 'var(--theme-color-fg-default)',
|
||||||
|
|
||||||
|
states: {
|
||||||
|
focus: {
|
||||||
|
borderColor: 'var(--destructive)',
|
||||||
|
boxShadow: '0 0 0 3px var(--destructive-alpha-20)',
|
||||||
|
outline: 'none'
|
||||||
|
},
|
||||||
|
hover: {
|
||||||
|
borderColor: 'var(--destructive-hover)'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
opacity: '0.5',
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
backgroundColor: 'var(--theme-color-bg-2)',
|
||||||
|
color: 'var(--theme-color-fg-default-shy)'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
color: 'var(--theme-color-fg-default-shy)',
|
||||||
|
opacity: '0.6'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
export { ButtonConfig } from './ButtonConfig';
|
export { ButtonConfig } from './ButtonConfig';
|
||||||
export { TextConfig } from './TextConfig';
|
export { TextConfig } from './TextConfig';
|
||||||
|
export { GroupConfig } from './GroupConfig';
|
||||||
// Other configs to be implemented:
|
export { TextInputConfig } from './TextInputConfig';
|
||||||
// export { GroupConfig } from './GroupConfig';
|
export { ImageConfig } from './ImageConfig';
|
||||||
// export { TextInputConfig } from './TextInputConfig';
|
|
||||||
// export { ImageConfig } from './ImageConfig';
|
|
||||||
|
|||||||
@@ -25,11 +25,14 @@ export * from './configs';
|
|||||||
*/
|
*/
|
||||||
export function initElementConfigs(): void {
|
export function initElementConfigs(): void {
|
||||||
// Import configs and register them
|
// Import configs and register them
|
||||||
import('./configs').then(({ ButtonConfig, TextConfig }) => {
|
import('./configs').then(({ ButtonConfig, TextConfig, GroupConfig, TextInputConfig, ImageConfig }) => {
|
||||||
// Import registry from local module
|
// Import registry from local module
|
||||||
import('./ElementConfigRegistry').then(({ ElementConfigRegistry }) => {
|
import('./ElementConfigRegistry').then(({ ElementConfigRegistry }) => {
|
||||||
ElementConfigRegistry.instance.register(ButtonConfig);
|
ElementConfigRegistry.instance.register(ButtonConfig);
|
||||||
ElementConfigRegistry.instance.register(TextConfig);
|
ElementConfigRegistry.instance.register(TextConfig);
|
||||||
|
ElementConfigRegistry.instance.register(GroupConfig);
|
||||||
|
ElementConfigRegistry.instance.register(TextInputConfig);
|
||||||
|
ElementConfigRegistry.instance.register(ImageConfig);
|
||||||
|
|
||||||
console.log('[ElementConfigs] Initialized with', ElementConfigRegistry.instance.getCount(), 'configs');
|
console.log('[ElementConfigs] Initialized with', ElementConfigRegistry.instance.getCount(), 'configs');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user