Skip to content

Latest commit

 

History

History
256 lines (183 loc) · 12.9 KB

File metadata and controls

256 lines (183 loc) · 12.9 KB

cligrid v2 — Roadmap

Chaque tâche est autonome : implémentation + tests + lint + commit. Cocher une tâche = mergé sur main, testé, prêt.


Phase 1 — Fondations critiques

1.1 Unicode / Emoji width

Le pipeline utilise text.length partout — les caractères multi-cellules (emoji, CJK) cassent le layout, l'overflow, et l'alignement.

  • 1.1.1 Ajouter une fonction stringWidth(text) qui retourne la largeur visible (gérer half/full-width, emoji, zero-width joiners)
  • 1.1.2 Remplacer text.length par stringWidth() dans ScreenBuffer.write()
  • 1.1.3 Adapter applyOverflow() (hidden, ellipsis) pour utiliser stringWidth()
  • 1.1.4 Adapter applySegmentOverflow() (toutes les fonctions : truncate, wrap, wrap-word) pour utiliser stringWidth()
  • 1.1.5 Adapter segmentsWidth() et le calcul d'alignement dans le renderer
  • 1.1.6 Tests : emoji (👍, 🎮), CJK (漢字), zero-width joiners, mixed ASCII + wide chars
  • 1.1.7 Lint, commit : feat: add Unicode width-aware text rendering

1.2 Styles supplémentaires (italic, strikethrough, inverse)

Codes ANSI existants, pas supportés. Effort minimal, impact visuel immédiat.

  • 1.2.1 Ajouter italic, strikethrough, inverse dans le type Style (style.ts)
  • 1.2.2 Ajouter les champs correspondants dans le type Cell (screenBuffer.ts)
  • 1.2.3 Mettre à jour stylize() dans ansi.ts pour émettre les codes ANSI (\x1b[3m italic, \x1b[9m strikethrough, \x1b[7m inverse)
  • 1.2.4 Mettre à jour ScreenBuffer.diff() pour comparer les nouveaux champs
  • 1.2.5 Propager dans le renderer (drawComponentToBuffer) et les segments
  • 1.2.6 Tests : rendu avec italic, strikethrough, inverse, combinaisons
  • 1.2.7 Lint, commit : feat: add italic, strikethrough, and inverse text styles

1.3 Système d'animation natif

Remplacer le pattern setInterval + setState par un moteur d'animation intégré.

  • 1.3.1 Créer src/utils/easing.ts avec les fonctions : linear, easeIn, easeOut, easeInOut, bounce, elastic
  • 1.3.2 Tests unitaires pour chaque fonction d'easing (valeurs aux bornes 0, 0.5, 1)
  • 1.3.3 Créer src/entities/animator.ts — classe Animator avec boucle setInterval cadencée (target ~30fps)
    • animate(from, to, duration, easing, onUpdate, onComplete)
    • cancel(id)
    • destroy()
  • 1.3.4 Tests unitaires pour Animator : interpolation, cancel, destroy, durée
  • 1.3.5 Intégrer Animator dans App : app.animate(component, propsTarget, options)
  • 1.3.6 Ajouter app.tick(callback) — enregistrer un callback appelé à chaque frame
  • 1.3.7 Batch des renders : accumuler les dirty components dans un frame avant flush
  • 1.3.8 Tests d'intégration : animer une prop, vérifier les valeurs interpolées
  • 1.3.9 Lint, commit : feat: add built-in animation system with easing functions

1.4 Couleurs — gradients et manipulation

Module utilitaire pour travailler avec les couleurs programmatiquement.

  • 1.4.1 Créer src/utils/color.ts avec les fonctions de parsing : parseHex, hexToRgb, rgbToHex
  • 1.4.2 Ajouter lighten(color, amount), darken(color, amount) (opérations HSL)
  • 1.4.3 Ajouter mix(colorA, colorB, ratio) — interpolation linéaire RGB
  • 1.4.4 Ajouter gradient(colorA, colorB, steps) — retourne un tableau de couleurs hex
  • 1.4.5 Tests unitaires : lighten/darken aux bornes, mix 0/0.5/1, gradient steps
  • 1.4.6 Exporter depuis src/index.ts
  • 1.4.7 Lint, commit : feat: add color manipulation utilities (gradient, lighten, darken, mix)

Phase 2 — Layout avancé

2.1 Gap dans flex layout

Espacement uniforme entre les enfants flex, comme CSS gap.

  • 2.1.1 Ajouter gap?: number dans ComponentConfig et Component
  • 2.1.2 Implémenter dans Template.layoutFlex() : insérer gap pixels entre chaque enfant
  • 2.1.3 Tests : row avec gap, column avec gap, gap=0, gap avec flex children
  • 2.1.4 Lint, commit : feat: add gap property for flex layout spacing

2.2 Min/Max dimensions

Contraintes de taille pour les layouts responsifs.

  • 2.2.1 Ajouter minWidth, maxWidth, minHeight, maxHeight dans ComponentConfig
  • 2.2.2 Appliquer les contraintes dans Template.resolveSize() et Template.layoutFlex()
  • 2.2.3 Tests : min clamp, max clamp, pourcentage avec contraintes, flex avec min/max
  • 2.2.4 Lint, commit : feat: add min/max dimension constraints

2.3 Justify et align dans flex

Distribution de l'espace entre les enfants et alignement sur l'axe transversal.

  • 2.3.1 Ajouter justify?: "start" | "center" | "end" | "space-between" | "space-around" dans ComponentConfig
  • 2.3.2 Ajouter alignItems?: "start" | "center" | "end" | "stretch" dans ComponentConfig
  • 2.3.3 Implémenter justify dans Template.layoutFlex() — redistribuer l'espace libre
  • 2.3.4 Implémenter alignItems dans Template.layoutFlex() — positionner sur l'axe transversal
  • 2.3.5 Tests : chaque combinaison justify × direction, alignItems center/stretch
  • 2.3.6 Lint, commit : feat: add justify and alignItems for flex layout

Phase 3 — Composants essentiels

3.1 Table

Composant le plus demandé pour les CLI.

  • 3.1.1 Créer src/components/table.ts — props : columns: { key, label, width?, align? }[], rows: Record<string, string>[]
  • 3.1.2 Render : header stylé (bold/underline), séparateurs, colonnes alignées, support segments par cellule
  • 3.1.3 Support du scroll vertical si les rows dépassent la hauteur
  • 3.1.4 Tests : rendu basique, colonnes alignées, overflow, scroll, styles
  • 3.1.5 Exporter depuis src/components/index.ts et src/index.ts
  • 3.1.6 Lint, commit : feat: add Table component with column alignment and scroll

3.2 Spinner / Loader

Indicateur de chargement animé. Dépend de 1.3 (animation system).

  • 3.2.1 Créer src/components/spinner.ts — props : label?: string, style?: "dots" | "line" | "arc" | "bouncingBar"
  • 3.2.2 Frames prédéfinis pour chaque style (ex: dots = ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏)
  • 3.2.3 Utiliser app.tick() ou animation interne pour cycler les frames
  • 3.2.4 Tests : cycle des frames, label affiché, styles différents
  • 3.2.5 Exporter depuis src/components/index.ts et src/index.ts
  • 3.2.6 Lint, commit : feat: add Spinner component with multiple animation styles

3.3 Tabs

Navigation par onglets.

  • 3.3.1 Créer src/components/tabs.ts — props : tabs: { label: string, id: string }[], activeTab: string
  • 3.3.2 Render : barre d'onglets (segments colorés pour actif/inactif), panneau actif
  • 3.3.3 Keyboard : Left/Right pour changer d'onglet, callback onTabChange(id)
  • 3.3.4 Tests : rendu, navigation, callback, styles actif/inactif
  • 3.3.5 Exporter depuis src/components/index.ts et src/index.ts
  • 3.3.6 Lint, commit : feat: add Tabs component with keyboard navigation

3.4 Modal / Dialog

Overlay modal avec focus trap.

  • 3.4.1 Créer src/components/modal.ts — props : title, body, buttons: { label, action, style? }[]
  • 3.4.2 Render : bordure, titre centré, body, boutons en row (segments), fond semi-opaque
  • 3.4.3 Focus trap : Tab cycle uniquement entre les boutons du modal
  • 3.4.4 Intégration avec app.showOverlay() / app.hideOverlay()
  • 3.4.5 Tests : rendu, focus trap, bouton callback, fermeture
  • 3.4.6 Lint, commit : feat: add Modal component with focus trap and button actions

3.5 Checkbox / Toggle

Input booléen.

  • 3.5.1 Créer src/components/checkbox.ts — props : checked: boolean, label: string
  • 3.5.2 Render : [✓] Label / [ ] Label avec segments (checkbox colorée)
  • 3.5.3 Keyboard : Space/Enter pour toggle, callback onChange(checked)
  • 3.5.4 Tests : rendu checked/unchecked, toggle, callback
  • 3.5.5 Exporter depuis src/components/index.ts et src/index.ts
  • 3.5.6 Lint, commit : feat: add Checkbox component with toggle support

Phase 4 — Input avancé

4.1 Support souris

Ouvre un nouveau paradigme d'interaction.

  • 4.1.1 Activer le mouse tracking ANSI dans InputManager (\x1b[?1003h enable, \x1b[?1003l disable)
  • 4.1.2 Parser les séquences souris SGR (\x1b[<button;x;y;M/m) dans InputManager
  • 4.1.3 Ajouter le type MouseEvent : { x, y, button: "left"|"right"|"middle", type: "click"|"release"|"move"|"scroll" }
  • 4.1.4 Hit-testing : déterminer quel composant est sous les coordonnées (x, y) via absolutePosition
  • 4.1.5 Émettre click, mousedown, mouseup sur les composants ciblés
  • 4.1.6 Émettre scroll (wheel up/down) sur le composant ciblé
  • 4.1.7 Tests : parsing des séquences, hit-testing, events émis, enable/disable
  • 4.1.8 Lint, commit : feat: add mouse support with click and scroll events

4.2 Hover

Détection du survol pour feedback visuel.

  • 4.2.1 Tracker la position courante de la souris dans InputManager
  • 4.2.2 Émettre mouseenter / mouseleave quand la souris entre/sort de la zone d'un composant
  • 4.2.3 Ajouter hovered: boolean dans RenderContext pour que les composants adaptent leur rendu
  • 4.2.4 Tests : enter/leave events, hovered state dans RenderContext
  • 4.2.5 Lint, commit : feat: add hover detection with mouseenter/mouseleave events

Phase 5 — Theming & polish

5.1 Système de thèmes

Tokens de design pour changer l'apparence globalement.

  • 5.1.1 Créer src/entities/theme.ts — type Theme : map de tokens (primary, danger, surface, text, border, muted, etc.)
  • 5.1.2 Theme par défaut (dark) et light
  • 5.1.3 app.setTheme(theme) — stocke le thème actif
  • 5.1.4 Résolution des tokens dans le renderer : si fg: "primary", résoudre via le thème actif
  • 5.1.5 Tests : résolution des tokens, changement de thème, fallback si token inconnu
  • 5.1.6 Lint, commit : feat: add theme system with design tokens

5.2 Focus visible

Indicateur visuel automatique du composant focusé.

  • 5.2.1 Ajouter focusStyle?: Partial<Style> dans ComponentConfig (style appliqué quand focused)
  • 5.2.2 Dans le renderer, merger focusStyle quand context.focused === true
  • 5.2.3 Style par défaut : bordure highlight ou fg changé
  • 5.2.4 Tests : style appliqué/non-appliqué selon focus, merge correct
  • 5.2.5 Lint, commit : feat: add visible focus indicator with focusStyle

5.3 Scroll horizontal

Actuellement vertical uniquement.

  • 5.3.1 Ajouter scrollX offset et totalColumns tracking dans Component
  • 5.3.2 Ajouter scrollToX(), scrollByX() methods
  • 5.3.3 Adapter le renderer pour appliquer le scroll horizontal sur les segments
  • 5.3.4 Keyboard : Left/Right pour scroller horizontalement quand focused
  • 5.3.5 Indicateur de scroll horizontal
  • 5.3.6 Tests : scroll horizontal, clamping, indicateur
  • 5.3.7 Lint, commit : feat: add horizontal scrolling support

Phase 6 — Démos v2

6.1 Démo showcase

Une démo combinant toutes les nouvelles features en un dashboard impressionnant.

  • 6.1.1 Créer demo/showcase-v2.ts : Table avec données, Tabs pour naviguer, Spinner pendant le chargement, Modal de confirmation, animations de transition, gradients de couleur, emoji dans le texte
  • 6.1.2 Ajouter le script demo:showcase dans package.json
  • 6.1.3 Tester visuellement sur terminal 80x24 minimum
  • 6.1.4 Lint, commit : feat: add v2 showcase demo

6.2 Release v2

  • 6.2.1 Mettre à jour README.md avec toutes les nouvelles features
  • 6.2.2 Mettre à jour CHANGELOG.md pour la v2.0.0
  • 6.2.3 Bump package.json version à 2.0.0
  • 6.2.4 Commit : chore: bump version to 2.0.0
  • 6.2.5 Push, créer la GitHub Release v2.0.0

Résumé des dépendances

Phase 1 (fondations)     Phase 2 (layout)      Phase 3 (composants)
├── 1.1 Unicode width    ├── 2.1 Gap           ├── 3.1 Table
├── 1.2 Italic/strike    ├── 2.2 Min/Max       ├── 3.2 Spinner ← dépend 1.3
├── 1.3 Animations       └── 2.3 Justify       ├── 3.3 Tabs
└── 1.4 Couleurs                               ├── 3.4 Modal
                                                └── 3.5 Checkbox

Phase 4 (input)          Phase 5 (polish)      Phase 6 (release)
├── 4.1 Souris           ├── 5.1 Thèmes        ├── 6.1 Démo showcase
└── 4.2 Hover ← 4.1     ├── 5.2 Focus visible  └── 6.2 Release v2
                         └── 5.3 Scroll H