@nomosui/react 0.4.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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/SKILL.md +166 -0
  4. package/dist/index.js +4591 -0
  5. package/dist/mcp/bin.js +46371 -0
  6. package/dist/types/catalogue/contract.d.ts +78 -0
  7. package/dist/types/catalogue/registry.d.ts +33 -0
  8. package/dist/types/components/alert/alert.d.ts +30 -0
  9. package/dist/types/components/alert/manifest.d.ts +3 -0
  10. package/dist/types/components/badge/badge.d.ts +25 -0
  11. package/dist/types/components/badge/manifest.d.ts +7 -0
  12. package/dist/types/components/button/button.d.ts +38 -0
  13. package/dist/types/components/button/manifest.d.ts +7 -0
  14. package/dist/types/components/card/card.d.ts +12 -0
  15. package/dist/types/components/card/manifest.d.ts +3 -0
  16. package/dist/types/components/checkbox/checkbox.d.ts +4 -0
  17. package/dist/types/components/checkbox/manifest.d.ts +3 -0
  18. package/dist/types/components/chip/chip.d.ts +36 -0
  19. package/dist/types/components/chip/manifest.d.ts +3 -0
  20. package/dist/types/components/counter/counter.d.ts +14 -0
  21. package/dist/types/components/counter/manifest.d.ts +3 -0
  22. package/dist/types/components/data-table-pagination/data-table-pagination.d.ts +20 -0
  23. package/dist/types/components/data-table-pagination/manifest.d.ts +3 -0
  24. package/dist/types/components/data-table-toolbar/data-table-toolbar.d.ts +34 -0
  25. package/dist/types/components/data-table-toolbar/manifest.d.ts +3 -0
  26. package/dist/types/components/empty-state/empty-state.d.ts +23 -0
  27. package/dist/types/components/empty-state/manifest.d.ts +3 -0
  28. package/dist/types/components/facet-filter/facet-filter.d.ts +23 -0
  29. package/dist/types/components/facet-filter/manifest.d.ts +6 -0
  30. package/dist/types/components/field/field.d.ts +15 -0
  31. package/dist/types/components/field/manifest.d.ts +3 -0
  32. package/dist/types/components/fieldset/fieldset.d.ts +3 -0
  33. package/dist/types/components/fieldset/manifest.d.ts +3 -0
  34. package/dist/types/components/form/form.d.ts +14 -0
  35. package/dist/types/components/form/manifest.d.ts +3 -0
  36. package/dist/types/components/freshness/freshness.d.ts +18 -0
  37. package/dist/types/components/freshness/manifest.d.ts +7 -0
  38. package/dist/types/components/input/input.d.ts +6 -0
  39. package/dist/types/components/input/manifest.d.ts +6 -0
  40. package/dist/types/components/label/label.d.ts +3 -0
  41. package/dist/types/components/label/manifest.d.ts +3 -0
  42. package/dist/types/components/meter/manifest.d.ts +6 -0
  43. package/dist/types/components/meter/meter.d.ts +23 -0
  44. package/dist/types/components/number-field/manifest.d.ts +3 -0
  45. package/dist/types/components/number-field/number-field.d.ts +7 -0
  46. package/dist/types/components/progress-bar/manifest.d.ts +3 -0
  47. package/dist/types/components/progress-bar/progress-bar.d.ts +12 -0
  48. package/dist/types/components/radio/manifest.d.ts +3 -0
  49. package/dist/types/components/radio/radio.d.ts +5 -0
  50. package/dist/types/components/rating/manifest.d.ts +3 -0
  51. package/dist/types/components/rating/rating.d.ts +19 -0
  52. package/dist/types/components/search-field/manifest.d.ts +3 -0
  53. package/dist/types/components/search-field/search-field.d.ts +14 -0
  54. package/dist/types/components/separator/manifest.d.ts +3 -0
  55. package/dist/types/components/separator/separator.d.ts +7 -0
  56. package/dist/types/components/skeleton/manifest.d.ts +3 -0
  57. package/dist/types/components/skeleton/skeleton.d.ts +3 -0
  58. package/dist/types/components/switch/manifest.d.ts +3 -0
  59. package/dist/types/components/switch/switch.d.ts +4 -0
  60. package/dist/types/components/table/manifest.d.ts +7 -0
  61. package/dist/types/components/table/table.d.ts +14 -0
  62. package/dist/types/components/textarea/manifest.d.ts +3 -0
  63. package/dist/types/components/textarea/textarea.d.ts +3 -0
  64. package/dist/types/components/timeline/manifest.d.ts +3 -0
  65. package/dist/types/components/timeline/timeline.d.ts +19 -0
  66. package/dist/types/components/toast/manifest.d.ts +3 -0
  67. package/dist/types/components/toast/toast.d.ts +35 -0
  68. package/dist/types/components/toggle/manifest.d.ts +3 -0
  69. package/dist/types/components/toggle/toggle.d.ts +31 -0
  70. package/dist/types/components/toggle-group/manifest.d.ts +6 -0
  71. package/dist/types/components/toggle-group/toggle-group.d.ts +8 -0
  72. package/dist/types/components/tree/manifest.d.ts +7 -0
  73. package/dist/types/components/tree/tree.d.ts +42 -0
  74. package/dist/types/features/data-table-features.d.ts +29 -0
  75. package/dist/types/features/faceted-data-table.d.ts +99 -0
  76. package/dist/types/features/toast.d.ts +33 -0
  77. package/dist/types/index.d.ts +112 -0
  78. package/dist/types/internal/dropdown-menu.d.ts +27 -0
  79. package/dist/types/internal/select.d.ts +13 -0
  80. package/dist/types/internal/sheet.d.ts +25 -0
  81. package/dist/types/internal/tooltip.d.ts +7 -0
  82. package/dist/types/lib/cn.d.ts +6 -0
  83. package/dist/types/lib/tone.d.ts +12 -0
  84. package/dist/types/tokens/build.d.mts +68 -0
  85. package/dist/types/tokens/resource.d.ts +8 -0
  86. package/dist/types/tokens/skin.d.ts +9 -0
  87. package/package.json +107 -0
  88. package/scripts/install-skill.mjs +28 -0
  89. package/tokens/theme.css +63 -0
  90. package/tokens/tokens.generated.css +271 -0
  91. package/tokens/tokens.json +225 -0
  92. package/tokens/tokens.resource.json +138 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pierre Tsia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # Nomos
2
+
3
+ **The laws of the interface.** An app-agnostic design system: a core of semantic tokens and
4
+ React primitives, exposed to humans (a catalog) and to agents (an MCP server), and built in
5
+ public.
6
+
7
+ Nomos names the **visual layer only** — tokens, primitives, catalog, MCP server. It knows
8
+ nothing about an app's state, i18n, router, or data. An app's identity is a **skin**: a token
9
+ overlay the app owns, never the core.
10
+
11
+ ## Layout
12
+
13
+ - `src/components/<name>/` — catalogued atoms and blocks. Each one ships three pieces: the
14
+ component (with its cva config), a hand-written `manifest.ts` (props, variants, usages,
15
+ ADR 0005), and one entry in `src/catalogue/registry.ts`. One inventory, two renderings: a
16
+ style page for a human, the MCP server for an agent.
17
+ - `src/features/` — behaviours the kit can render (`FacetedDataTable`), exported but not
18
+ catalogued. They carry state and receive injected `labels`; the core has no i18n.
19
+ - `src/internal/` — the raw Radix primitives the atoms and features compose. Plumbing, not
20
+ pieces.
21
+ - `src/mcp/` — the local stdio MCP server and the `ui://nomos/<name>` views.
22
+ - `tokens/` — `tokens.json` (DTCG) is the single source; `tokens.generated.css` and
23
+ `tokens.resource.json` are committed renderings, never edited by hand.
24
+
25
+ ## The boundary rule
26
+
27
+ Imports go one way: an app may import Nomos, Nomos never imports app code. Inside the
28
+ package, imports go through `@nomos/*` and never through a relative path — ESLint enforces
29
+ it.
30
+
31
+ ## Development
32
+
33
+ ```sh
34
+ npm ci
35
+ npm test # vitest, jsdom
36
+ npm run lint
37
+ npm run typecheck
38
+ npm run mcp # the stdio MCP server against the source
39
+ ```
40
+
41
+ Generated artifacts are committed and replayed by a script; CI fails if one has drifted:
42
+
43
+ ```sh
44
+ npm run tokens # tokens.generated.css + tokens.resource.json
45
+ npm run build:view # src/mcp/view.generated.ts
46
+ npm run build:view-css # src/mcp/view-css.generated.ts
47
+ npm run build:surface # surface.generated.json (the public surface snapshot)
48
+ ```
49
+
50
+ Build and smoke-test the distributable package:
51
+
52
+ ```sh
53
+ npm run build:package # dist/index.js + dist/mcp/bin.js + types
54
+ npm run smoke:consumer # installs the tarball in a fresh project and exercises it
55
+ ```
56
+
57
+ ## Decisions
58
+
59
+ The structural decisions live in `docs/adr/`. Start with 0002 (app-agnostic core), 0003 (the
60
+ theme interface), 0004 (`tokens.json` as the single source), 0005 (the catalogue manifest),
61
+ 0017 (the name), 0024 (the public surface) and 0026 (Nomos goes public).
62
+
63
+ ## License
64
+
65
+ MIT — see [LICENSE](LICENSE).
package/SKILL.md ADDED
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: nomos
3
+ description: Choisir la brique du design system Nomos pour un usage donné — atomes (Badge, Chip, Meter, Freshness, Table, Button, Input, champ, blocs de formulaire), coquille de table, vocabulaire de tons, tokens et densité — et interroger le catalogue par le serveur MCP local, y compris les vues `ui://` rendues en conversation.
4
+ ---
5
+
6
+ # Le design system Nomos
7
+
8
+ Un **cœur app-agnostique** (la racine de ce dépôt) : il ne connaît ni l'état d'une
9
+ app, ni son i18n, ni son router, ni ses query-params. Dès qu'il faut nommer un produit
10
+ pour expliquer une brique, elle appartient à l'app, pas au cœur.
11
+
12
+ ## Quelle brique prendre
13
+
14
+ ### Qualifier, situer
15
+
16
+ - **Qualifier d'un mot court** (un statut, un domaine) → `Badge`. Le ton vient d'une
17
+ classe de `toneClasses`, jamais d'un mot produit.
18
+ - **Qualifier de façon retirable** (un filtre actif) → `Chip`, avec `onRemove` ; sans
19
+ action, un `Chip` nu. Un statut qu'on ne retire pas reste un `Badge`.
20
+ - **Situer une valeur sur une échelle**, avec un seuil → `Meter` (barre large) ou
21
+ `CompactMeter` (cellule dense). Le texte du seuil est injecté par l'appelant.
22
+ - **Dire l'âge d'une donnée** → `Freshness` ; l'âge est déjà formaté, `stale` est décidé
23
+ par l'appelant.
24
+ - **Montrer l'avancement d'une tâche** (un total, sans seuil) → `ProgressBar`, sémantique
25
+ `progressbar`.
26
+ - **Mettre un chiffre en avant** → `Counter` (suffixe et libellé fournis par l'app).
27
+ - **Recueillir ou montrer une note** → `Rating` : interactif seulement si l'app fournit
28
+ `onValueChange`, sinon un affichage.
29
+ - **Lister des événements datés** → `Timeline` (frise, présentation seule ; le format de
30
+ la date vient de l'app).
31
+
32
+ ### Agir, saisir
33
+
34
+ - **Agir** → `Button` (`variant` = le ton, `size` = la densité ; `asChild` pour poser le
35
+ style sur un lien).
36
+ - **Saisir une ligne** → `Input` ; **un nombre borné** → `NumberField` (`step`, `min`,
37
+ `max` du natif) ; **chercher avec icône et effacement** → `SearchField` ; **plusieurs
38
+ lignes** → `Textarea`.
39
+ - **Cocher** → `Checkbox` (option indépendante) ; **basculer tout de suite** → `Switch` ;
40
+ **choisir une seule option parmi quelques-unes** → `RadioGroup` ; **une bascule
41
+ ponctuelle** (mode, filtre) → `Toggle`, **un segment** → `ToggleGroup`. Tous sont
42
+ contrôlés par props : l'état reste dans l'app.
43
+
44
+ ### Structurer
45
+
46
+ - **Une surface** (titre, corps, pied) → les parts de `Card`.
47
+ - **Un état vide, ou une panne à nommer** → `EmptyState` (la carte centrée ; le `detail`
48
+ brut nomme la vraie panne, plutôt qu'un zéro silencieux).
49
+ - **Une information inline** qui demande l'attention sans bloquer → `Alert` (le ton vient
50
+ du cœur ; `onClose` va avec `closeLabel`).
51
+ - **Séparer deux contenus** → `Separator` ; **tenir la place d'un contenu qui charge** →
52
+ `Skeleton`.
53
+ - **Prévenir sans bloquer** → `Toast` via `useToast().show({ message })` (la file et
54
+ l'auto-dismiss vivent dans `ToastProvider`).
55
+ - **Parcourir une hiérarchie** → `Tree` (navigation, un nœud actif) ou `SelectionTree`
56
+ (sélection multiple) ; ouverture et sélection sont contrôlées par props, le focus
57
+ clavier (rôle `tree`, flèches) est interne.
58
+
59
+ ### Formulaire
60
+
61
+ - **Mettre en page** → `Form` (grille de champs + zone d'actions, `columns` pour deux
62
+ colonnes). Aucune validation, aucun état, aucun texte.
63
+ - **Un emplacement de champ** (libellé, contrôle, aide ou erreur) → `Field` ; **nommer un
64
+ contrôle seul** → `Label` (`htmlFor`) ; **regrouper des champs apparentés** →
65
+ `Fieldset` (`legend` fourni par l'app). Le message d'erreur est injecté, jamais calculé
66
+ par le cœur.
67
+
68
+ ### Tables
69
+
70
+ - **Une grille dense de lignes** → les parts de `Table` (`Table`, `TableHeader`,
71
+ `TableBody`, `TableRow`, `TableHead`, `TableCell`), importables séparément.
72
+ - **Filtrer par une dimension** → `FacetFilter` (options, sélection et libellé « effacer »
73
+ injectés) ; **rechercher, compter, gérer les colonnes** → `DataTableToolbar` ;
74
+ **naviguer dans une page** → `DataTablePagination` (indépendante de la table).
75
+ - **Une table pilotée** (colonnes, facettes, tri, pagination, détail de ligne) → la
76
+ feature `FacetedDataTable` : elle possède le comportement et le **placement** du détail
77
+ (surcouche `overlay` ou dépli `inline`), l'app fournit le contenu et les `labels`.
78
+
79
+ ### Tons et tokens
80
+
81
+ - **Un ton de statut** → `toneClasses` (`neutral`, `info`, `progress`, `attention`,
82
+ `warning`, `danger`, `success`). C'est une **intention**, pas une couleur.
83
+ - **Couleurs, espacement, typographie** → les tokens (`tokens.json`, source unique). Le
84
+ thème et la densité se posent sur la **racine du rendu** (`data-theme`, `data-density`),
85
+ jamais sur `:root`.
86
+
87
+ Le tri par défaut est porté par la colonne (`meta.defaultSort`), jamais par le cœur.
88
+
89
+ ## L'inventaire
90
+
91
+ La liste exacte des briques du catalogue, tenue par test (`src/mcp/skill.test.ts`) : une
92
+ brique ajoutée au catalogue sans être ici fait rougir, et une ligne qui n'existe plus
93
+ aussi.
94
+
95
+ <!-- inventaire : début — tenu par src/mcp/skill.test.ts -->
96
+ alert
97
+ badge
98
+ button
99
+ card
100
+ checkbox
101
+ chip
102
+ counter
103
+ data-table-pagination
104
+ data-table-toolbar
105
+ empty-state
106
+ facet-filter
107
+ field
108
+ fieldset
109
+ form
110
+ freshness
111
+ input
112
+ label
113
+ meter
114
+ number-field
115
+ progress-bar
116
+ radio
117
+ rating
118
+ search-field
119
+ separator
120
+ skeleton
121
+ switch
122
+ table
123
+ textarea
124
+ timeline
125
+ toast
126
+ toggle
127
+ toggle-group
128
+ tree
129
+ <!-- inventaire : fin -->
130
+
131
+ ## Interroger le catalogue
132
+
133
+ Le serveur MCP local sert le même inventaire que la page de style, en lecture seule :
134
+
135
+ ```sh
136
+ npm run mcp # stdio, sans jeton
137
+ ```
138
+
139
+ - `list_components { query? }` — quelles briques existent, et laquelle correspond à un mot.
140
+ - `get_component { name }` — le contrat complet d'une brique (props, variantes, usages).
141
+ - `preview_component { name }` — sa recette de rendu (exemple de props, variantes, usages).
142
+ - `list_scenes` — les **scènes composites** disponibles.
143
+ - `render_<nom>` / `render_scene_<nom>` — renvoient la recette, **portent les données**
144
+ (`props`, optionnel) et **référencent la vue** par `_meta.ui.resourceUri`.
145
+
146
+ Les ressources portent les mêmes données que les outils : `nomos://tokens` (l'inventaire
147
+ aplati par mode) et `nomos://component/<nom>` (le manifeste).
148
+
149
+ ## Le rendu en conversation
150
+
151
+ Au-delà du manifeste, chaque brique a une **vue** servie en `ui://nomos/<nom>` — un
152
+ document auto-suffisant (`text/html;profile=mcp-app`) que l'hôte rend dans un iframe
153
+ sandboxé. Une **scène composite** (`ui://nomos/composite/<nom>`) assemble plusieurs
154
+ briques en un écran qui a du sens (un formulaire, une carte de statut).
155
+
156
+ La vue **émet des intentions** (`ready`, `select`, `change`, `error`) et ne mute jamais
157
+ l'état : l'hôte décide. Il lui pousse l'apparence (`set-view` : thème, densité) et les
158
+ **données** (`set-data`, ADR 0023) — les `props` que l'outil de rendu a portées.
159
+
160
+ ## Si tu changes le design system
161
+
162
+ Un changement qui change **l'usage** d'une brique met cette skill à jour dans le même
163
+ changement : la liste de l'inventaire et la prose. Un composant ajouté au catalogue sans
164
+ son manifeste (props, variantes, usages) fait rougir le test de cohérence
165
+ (`src/catalogue/coherence.test.ts`) ; une brique absente de l'inventaire fait rougir
166
+ `src/mcp/skill.test.ts`.