@nomosui/react 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -27,7 +27,8 @@ pour expliquer une brique, elle appartient à l'app, pas au cœur.
27
27
  - **Recueillir ou montrer une note** → `Rating` : interactif seulement si l'app fournit
28
28
  `onValueChange`, sinon un affichage.
29
29
  - **Lister des événements datés** → `Timeline` (frise, présentation seule ; le format de
30
- la date vient de l'app).
30
+ la date vient de l'app). Un point porte un état — `done` (défaut) ou `past` (grisé) —
31
+ et un `past` exige un `stateLabel` fourni par l'app : la couleur seule ne suffit pas.
31
32
  - **Nommer un contrôle iconique, glisser une aide courte** → `Tooltip` en famille (un
32
33
  `TooltipProvider` autour de plusieurs, `Tooltip`, `TooltipTrigger`, `TooltipContent`).
33
34
  Jamais pour une information essentielle : elle n'est ni au clavier seul ni au tactile.
@@ -116,7 +117,9 @@ pour expliquer une brique, elle appartient à l'app, pas au cœur.
116
117
  - **Un emplacement de champ** (libellé, contrôle, aide ou erreur) → `Field` ; **nommer un
117
118
  contrôle seul** → `Label` (`htmlFor`) ; **regrouper des champs apparentés** →
118
119
  `Fieldset` (`legend` fourni par l'app). Le message d'erreur est injecté, jamais calculé
119
- par le cœur.
120
+ par le cœur. Le `Field` associe lui-même le contrôle à son message (`aria-invalid`,
121
+ `aria-describedby`) pour les contrôles du cœur : `Input`, `Textarea`, `NumberField`,
122
+ `SearchField` et le déclencheur de `Select`.
120
123
 
121
124
  ### Tables
122
125
 
@@ -129,6 +132,23 @@ pour expliquer une brique, elle appartient à l'app, pas au cœur.
129
132
  feature `FacetedDataTable` : elle possède le comportement et le **placement** du détail
130
133
  (surcouche `overlay` ou dépli `inline`), l'app fournit le contenu et les `labels`.
131
134
 
135
+ ### Conversation
136
+
137
+ - **Brancher une conversation** → la feature `useChatThread({ transport, initialMessages })` :
138
+ elle possède la **machine à états** — ajout optimiste du tour, assemblage des deltas,
139
+ `send`, `stop`, `retry`/`regenerate`, `replace`, erreur — et **rien du transport**
140
+ (ADR 0032). L'app injecte un `ChatTransport` (une fonction `send`) : le cœur n'appelle
141
+ aucun modèle, ne connaît aucun endpoint, n'affiche aucune erreur réseau (ADR 0018). Un
142
+ message porte un rôle et des **parts** (`text`, `reasoning`, `tool`, `data`) : un signal
143
+ structuré est une part de premier ordre, jamais un sentinelle pêché dans la prose.
144
+ - **La fenêtre du fil** → `Conversation` : une région `log` vivante ancrée en bas, le
145
+ défilement tenu par le cœur, la hauteur par l'app. **Un message** → `Message` : le
146
+ placement et le ton du rôle, le contenu en `parts`, et `renderPart` pour que l'app
147
+ garde markdown, coloration et artefact métier. **La saisie** → `Composer` : contrôlé par
148
+ props (`value` + `onChange`), `Entrée` envoie, `Maj+Entrée` coupe la ligne, garde IME ;
149
+ `busy` + `onStop` pour interrompre. **Attendre la réponse** → `TypingIndicator` (libellé
150
+ injecté, région `status`).
151
+
132
152
  ### Tons et tokens
133
153
 
134
154
  - **Un ton de statut** → `toneClasses` (`neutral`, `info`, `progress`, `attention`,
@@ -158,6 +178,8 @@ chip
158
178
  code
159
179
  code-block
160
180
  collapsible
181
+ composer
182
+ conversation
161
183
  copy-button
162
184
  counter
163
185
  data-table-pagination
@@ -177,6 +199,7 @@ kicker
177
199
  label
178
200
  link
179
201
  meter
202
+ message
180
203
  navbar
181
204
  number-field
182
205
  popover
@@ -200,6 +223,7 @@ toggle
200
223
  toggle-group
201
224
  tooltip
202
225
  tree
226
+ typing-indicator
203
227
  <!-- inventaire : fin -->
204
228
 
205
229
  ## Interroger le catalogue
@@ -225,7 +249,10 @@ aplati par mode) et `nomos://component/<nom>` (le manifeste).
225
249
  Au-delà du manifeste, chaque brique a une **vue** servie en `ui://nomos/<nom>` — un
226
250
  document auto-suffisant (`text/html;profile=mcp-app`) que l'hôte rend dans un iframe
227
251
  sandboxé. Une **scène composite** (`ui://nomos/composite/<nom>`) assemble plusieurs
228
- briques en un écran qui a du sens (un formulaire, une carte de statut).
252
+ briques en un écran qui a du sens (un formulaire, une carte de statut). Les scènes
253
+ sont aussi exportées sur la surface publique JS (`composites`, `compositeNames`,
254
+ `findComposite`, ADR 0031) : le serveur MCP et le site rendent la **même** source,
255
+ et leur copie par défaut est neutre — elle s'injecte par props.
229
256
 
230
257
  La vue **émet des intentions** (`ready`, `select`, `change`, `error`) et ne mute jamais
231
258
  l'état : l'hôte décide. Il lui pousse l'apparence (`set-view` : thème, densité) et les