@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.
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/SKILL.md +166 -0
- package/dist/index.js +4591 -0
- package/dist/mcp/bin.js +46371 -0
- package/dist/types/catalogue/contract.d.ts +78 -0
- package/dist/types/catalogue/registry.d.ts +33 -0
- package/dist/types/components/alert/alert.d.ts +30 -0
- package/dist/types/components/alert/manifest.d.ts +3 -0
- package/dist/types/components/badge/badge.d.ts +25 -0
- package/dist/types/components/badge/manifest.d.ts +7 -0
- package/dist/types/components/button/button.d.ts +38 -0
- package/dist/types/components/button/manifest.d.ts +7 -0
- package/dist/types/components/card/card.d.ts +12 -0
- package/dist/types/components/card/manifest.d.ts +3 -0
- package/dist/types/components/checkbox/checkbox.d.ts +4 -0
- package/dist/types/components/checkbox/manifest.d.ts +3 -0
- package/dist/types/components/chip/chip.d.ts +36 -0
- package/dist/types/components/chip/manifest.d.ts +3 -0
- package/dist/types/components/counter/counter.d.ts +14 -0
- package/dist/types/components/counter/manifest.d.ts +3 -0
- package/dist/types/components/data-table-pagination/data-table-pagination.d.ts +20 -0
- package/dist/types/components/data-table-pagination/manifest.d.ts +3 -0
- package/dist/types/components/data-table-toolbar/data-table-toolbar.d.ts +34 -0
- package/dist/types/components/data-table-toolbar/manifest.d.ts +3 -0
- package/dist/types/components/empty-state/empty-state.d.ts +23 -0
- package/dist/types/components/empty-state/manifest.d.ts +3 -0
- package/dist/types/components/facet-filter/facet-filter.d.ts +23 -0
- package/dist/types/components/facet-filter/manifest.d.ts +6 -0
- package/dist/types/components/field/field.d.ts +15 -0
- package/dist/types/components/field/manifest.d.ts +3 -0
- package/dist/types/components/fieldset/fieldset.d.ts +3 -0
- package/dist/types/components/fieldset/manifest.d.ts +3 -0
- package/dist/types/components/form/form.d.ts +14 -0
- package/dist/types/components/form/manifest.d.ts +3 -0
- package/dist/types/components/freshness/freshness.d.ts +18 -0
- package/dist/types/components/freshness/manifest.d.ts +7 -0
- package/dist/types/components/input/input.d.ts +6 -0
- package/dist/types/components/input/manifest.d.ts +6 -0
- package/dist/types/components/label/label.d.ts +3 -0
- package/dist/types/components/label/manifest.d.ts +3 -0
- package/dist/types/components/meter/manifest.d.ts +6 -0
- package/dist/types/components/meter/meter.d.ts +23 -0
- package/dist/types/components/number-field/manifest.d.ts +3 -0
- package/dist/types/components/number-field/number-field.d.ts +7 -0
- package/dist/types/components/progress-bar/manifest.d.ts +3 -0
- package/dist/types/components/progress-bar/progress-bar.d.ts +12 -0
- package/dist/types/components/radio/manifest.d.ts +3 -0
- package/dist/types/components/radio/radio.d.ts +5 -0
- package/dist/types/components/rating/manifest.d.ts +3 -0
- package/dist/types/components/rating/rating.d.ts +19 -0
- package/dist/types/components/search-field/manifest.d.ts +3 -0
- package/dist/types/components/search-field/search-field.d.ts +14 -0
- package/dist/types/components/separator/manifest.d.ts +3 -0
- package/dist/types/components/separator/separator.d.ts +7 -0
- package/dist/types/components/skeleton/manifest.d.ts +3 -0
- package/dist/types/components/skeleton/skeleton.d.ts +3 -0
- package/dist/types/components/switch/manifest.d.ts +3 -0
- package/dist/types/components/switch/switch.d.ts +4 -0
- package/dist/types/components/table/manifest.d.ts +7 -0
- package/dist/types/components/table/table.d.ts +14 -0
- package/dist/types/components/textarea/manifest.d.ts +3 -0
- package/dist/types/components/textarea/textarea.d.ts +3 -0
- package/dist/types/components/timeline/manifest.d.ts +3 -0
- package/dist/types/components/timeline/timeline.d.ts +19 -0
- package/dist/types/components/toast/manifest.d.ts +3 -0
- package/dist/types/components/toast/toast.d.ts +35 -0
- package/dist/types/components/toggle/manifest.d.ts +3 -0
- package/dist/types/components/toggle/toggle.d.ts +31 -0
- package/dist/types/components/toggle-group/manifest.d.ts +6 -0
- package/dist/types/components/toggle-group/toggle-group.d.ts +8 -0
- package/dist/types/components/tree/manifest.d.ts +7 -0
- package/dist/types/components/tree/tree.d.ts +42 -0
- package/dist/types/features/data-table-features.d.ts +29 -0
- package/dist/types/features/faceted-data-table.d.ts +99 -0
- package/dist/types/features/toast.d.ts +33 -0
- package/dist/types/index.d.ts +112 -0
- package/dist/types/internal/dropdown-menu.d.ts +27 -0
- package/dist/types/internal/select.d.ts +13 -0
- package/dist/types/internal/sheet.d.ts +25 -0
- package/dist/types/internal/tooltip.d.ts +7 -0
- package/dist/types/lib/cn.d.ts +6 -0
- package/dist/types/lib/tone.d.ts +12 -0
- package/dist/types/tokens/build.d.mts +68 -0
- package/dist/types/tokens/resource.d.ts +8 -0
- package/dist/types/tokens/skin.d.ts +9 -0
- package/package.json +107 -0
- package/scripts/install-skill.mjs +28 -0
- package/tokens/theme.css +63 -0
- package/tokens/tokens.generated.css +271 -0
- package/tokens/tokens.json +225 -0
- 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`.
|