odoro 1.0.1 → 1.0.2

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 (46) hide show
  1. package/README.md +73 -0
  2. package/dist/cli.js +2 -2
  3. package/dist/{create-LTT3SAWT.js → create-GD6O2TPL.js} +107 -63
  4. package/dist/{package-LK46RV2I.js → package-VMTZDORI.js} +1 -1
  5. package/dist/registry/index.d.ts +2 -2
  6. package/package.json +1 -1
  7. package/templates/{react-ts-server/_variantes/avec-moteur/client/src/sections/Fond.tsx → react-ts/_variantes/avec-moteur/src/fond.tsx} +13 -13
  8. package/templates/react-ts/_variantes/sans-libs/src/App.tsx +250 -21
  9. package/templates/react-ts/_variantes/sans-libs/src/{sections/Fond.tsx → fond.tsx} +1 -1
  10. package/templates/react-ts/_variantes/sans-libs/src/styles.css +68 -35
  11. package/templates/react-ts/_variantes/sans-routeur/src/App.tsx +309 -24
  12. package/templates/react-ts/public/favicon.svg +2 -3
  13. package/templates/react-ts/src/App.tsx +422 -49
  14. package/templates/react-ts/src/{sections/Fond.tsx → fond.tsx} +9 -9
  15. package/templates/react-ts/src/router.tsx +72 -0
  16. package/templates/{react-ts/_variantes/avec-moteur/src/sections/Fond.tsx → react-ts-server/_variantes/avec-moteur/client/src/fond.tsx} +13 -13
  17. package/templates/react-ts-server/_variantes/sans-libs/client/src/App.tsx +250 -21
  18. package/templates/react-ts-server/_variantes/sans-libs/client/src/{sections/Fond.tsx → fond.tsx} +1 -1
  19. package/templates/react-ts-server/_variantes/sans-libs/client/src/styles.css +68 -35
  20. package/templates/react-ts-server/_variantes/sans-routeur/client/src/App.tsx +309 -24
  21. package/templates/react-ts-server/client/public/favicon.svg +2 -3
  22. package/templates/react-ts-server/client/src/App.tsx +422 -49
  23. package/templates/react-ts-server/client/src/{sections/Fond.tsx → fond.tsx} +9 -9
  24. package/templates/react-ts-server/client/src/router.tsx +72 -0
  25. package/templates/react-ts/_variantes/sans-libs/src/composants/Marque.tsx +0 -37
  26. package/templates/react-ts/_variantes/sans-libs/src/sections/Cloture.tsx +0 -60
  27. package/templates/react-ts/_variantes/sans-libs/src/sections/Hero.tsx +0 -92
  28. package/templates/react-ts/_variantes/sans-libs/src/sections/Piliers.tsx +0 -44
  29. package/templates/react-ts/src/composants/Marque.tsx +0 -50
  30. package/templates/react-ts/src/routes/About.tsx +0 -43
  31. package/templates/react-ts/src/routes/Home.tsx +0 -28
  32. package/templates/react-ts/src/routes/NotFound.tsx +0 -14
  33. package/templates/react-ts/src/sections/Cloture.tsx +0 -69
  34. package/templates/react-ts/src/sections/Hero.tsx +0 -119
  35. package/templates/react-ts/src/sections/Piliers.tsx +0 -68
  36. package/templates/react-ts-server/_variantes/sans-libs/client/src/composants/Marque.tsx +0 -37
  37. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Cloture.tsx +0 -60
  38. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Hero.tsx +0 -92
  39. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Piliers.tsx +0 -44
  40. package/templates/react-ts-server/client/src/composants/Marque.tsx +0 -50
  41. package/templates/react-ts-server/client/src/routes/About.tsx +0 -43
  42. package/templates/react-ts-server/client/src/routes/Home.tsx +0 -28
  43. package/templates/react-ts-server/client/src/routes/NotFound.tsx +0 -14
  44. package/templates/react-ts-server/client/src/sections/Cloture.tsx +0 -69
  45. package/templates/react-ts-server/client/src/sections/Hero.tsx +0 -119
  46. package/templates/react-ts-server/client/src/sections/Piliers.tsx +0 -68
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Le fond decoratif, en surface WebGL.
3
3
  *
4
- * Cette version remplace le degre statique parce que le moteur a ete retenu a
4
+ * Cette version remplace le degrade statique parce que le moteur a ete retenu a
5
5
  * la creation. Le reste de la page est inchange : elle place `<Fond />` et ne
6
6
  * sait pas ce qu'il y a derriere.
7
7
  *
@@ -12,20 +12,20 @@
12
12
  * ouverts, ou si l'appareil ne suivrait pas. Le refus est une valeur, pas une
13
13
  * exception : on affiche alors le degrade, et la page tient.
14
14
  *
15
- * **Le mouvement reduit.** Sous cette preference, rien n'est monte du tout :
16
- * le fond n'apportait que son mouvement, et la carte graphique n'a pas a
17
- * s'allumer pour un visiteur qui a demande le calme.
15
+ * **Le mouvement reduit.** Sous cette preference, rien n'est monte : le fond
16
+ * n'apportait que son mouvement, et la carte graphique n'a pas a s'allumer pour
17
+ * un visiteur qui a demande le calme.
18
18
  *
19
- * **Les couleurs du theme.** Les teintes sont lues dans les jetons, pas
20
- * ecrites dans le nuanceur. Une bascule clair / sombre les relit, et changer
19
+ * **Les couleurs du theme.** Les teintes sont lues dans les jetons, pas ecrites
20
+ * dans le nuanceur. Une bascule clair / sombre les relit, et changer
21
21
  * `--o-palette-brand-500` repeint le fond sans toucher a ce fichier.
22
22
  *
23
23
  * ## Pourquoi des styles en ligne
24
24
  *
25
25
  * Ce fichier est pose quel que soit le reste : un projet qui a decoche les
26
- * bibliotheques n'a pas les classes `o-*`, et une classe absente ne peint
27
- * rien — le fond aurait alors une hauteur nulle, sans que rien ne le signale.
28
- * Les quelques regles de placement sont donc ecrites ou elles sont sures.
26
+ * bibliotheques n'a pas les classes `o-*`, et une classe absente ne peint rien
27
+ * — le fond aurait alors une hauteur nulle, sans que rien ne le signale. Les
28
+ * quelques regles de placement sont donc ecrites ou elles sont sures.
29
29
  *
30
30
  * @module
31
31
  */
@@ -52,7 +52,7 @@ function Degrade(): ReactElement {
52
52
  opacity: 0.28,
53
53
  filter: 'blur(64px)',
54
54
  background:
55
- 'radial-gradient(60% 60% at 50% 0%, var(--o-palette-brand-500, #f97316), transparent)',
55
+ 'radial-gradient(60% 60% at 50% 0%, var(--o-palette-brand-500, #3b82f6), transparent)',
56
56
  }}
57
57
  />
58
58
  )
@@ -76,7 +76,7 @@ export function Fond(): ReactElement {
76
76
  if (a === undefined || b === undefined || c === undefined) return undefined
77
77
  // Le fond du theme domine, la marque n'est qu'un reflet : ces trois
78
78
  // couleurs vont dans un melange, et deux teintes de marque sur trois
79
- // donneraient une nappe orange en pleine page plutot qu'un halo.
79
+ // donneraient une nappe pleine page plutot qu'un halo.
80
80
  return { uColorA: c, uColorB: c, uColorC: a, uSpeed: 0.1, uScale: 1.4, uOctaves: 3 }
81
81
  }, [teintes])
82
82
 
@@ -106,8 +106,8 @@ export function Fond(): ReactElement {
106
106
  // pleine intensite la nappe passe devant le titre qu'elle est censee
107
107
  // porter ; a un cinquieme, elle le souligne.
108
108
  opacity: 0.2,
109
- // Le bas se dissout dans la page : une surface qui s'arrete net
110
- // dessine une ligne horizontale que rien ne justifie.
109
+ // Le bas se dissout dans la page : une surface qui s'arrete net dessine
110
+ // une ligne horizontale que rien ne justifie.
111
111
  maskImage: 'linear-gradient(to bottom, black 45%, transparent)',
112
112
  WebkitMaskImage: 'linear-gradient(to bottom, black 45%, transparent)',
113
113
  }}
@@ -1,40 +1,269 @@
1
- import type { ReactElement } from 'react'
2
-
3
- import { Marque } from '@/composants/Marque'
4
- import { Cloture } from '@/sections/Cloture'
5
- import { Fond } from '@/sections/Fond'
6
- import { Hero } from '@/sections/Hero'
7
- import { Piliers } from '@/sections/Piliers'
8
-
9
1
  /**
10
- * Racine de l'application.
2
+ * Toute la page, en un fichier.
11
3
  *
12
- * Les bibliotheques Odoro n'ont pas ete retenues a la creation : pas de
13
- * classes `o-*`, pas de jetons, pas de routeur. Le dessin est celui de la
14
- * version complete, porte par `styles.css` en CSS ordinaire.
4
+ * ## Sans les bibliotheques
5
+ *
6
+ * Elles n'ont pas ete retenues a la creation : pas de classes `o-*`, pas de
7
+ * jetons, pas de routeur. Le dessin est celui de la version complete — meme
8
+ * barre en gelules, meme titre, memes cartes — porte par `styles.css` en CSS
9
+ * ordinaire.
15
10
  *
16
11
  * Pour les ajouter plus tard : `npm i @odoro-cli/libs`, puis importer
17
- * `@odoro-cli/libs/styles.css` dans `main.tsx`.
12
+ * `@odoro-cli/libs/styles.css` dans `main.tsx` avant cette feuille.
13
+ *
14
+ * @module
18
15
  */
19
- export function App(): ReactElement {
16
+
17
+ import { useState, type ReactElement } from 'react'
18
+
19
+ import { Fond } from '@/fond'
20
+
21
+ /* -------------------------------------------------------------------------- */
22
+ /* Marque */
23
+ /* -------------------------------------------------------------------------- */
24
+
25
+ /** Le signe de la marque, a la taille demandee. */
26
+ function Signe({ taille = '1.75rem' }: { readonly taille?: string }): ReactElement {
20
27
  return (
21
- <div className="app-shell">
22
- <nav className="nav">
23
- <Marque />
24
- <a href="https://odoro.dev" target="_blank" rel="noreferrer" className="nav-lien">
28
+ <svg
29
+ viewBox="0 0 100 100"
30
+ fill="none"
31
+ aria-hidden="true"
32
+ style={{ width: taille, height: taille, flexShrink: 0 }}
33
+ >
34
+ <path
35
+ d="M20.25 20.25H50a29.75 29.75 0 1 1-29.75 29.75Z"
36
+ stroke="currentColor"
37
+ strokeWidth="10.5"
38
+ strokeLinejoin="miter"
39
+ />
40
+ </svg>
41
+ )
42
+ }
43
+
44
+ /* -------------------------------------------------------------------------- */
45
+ /* Barre de navigation */
46
+ /* -------------------------------------------------------------------------- */
47
+
48
+ /** La barre : la marque en gelule, et le lien vers le site. */
49
+ function Barre(): ReactElement {
50
+ return (
51
+ <header className="barre">
52
+ <div className="barre-contenu">
53
+ <span className="gelule marque">
54
+ <span className="marque-signe">
55
+ <Signe />
56
+ </span>
57
+ <span className="marque-mot">ODORO</span>
58
+ </span>
59
+
60
+ <a
61
+ href="https://odoro.dev"
62
+ target="_blank"
63
+ rel="noreferrer"
64
+ className="gelule gelule-lien"
65
+ >
25
66
  odoro.dev
26
67
  </a>
27
- </nav>
68
+ </div>
69
+ </header>
70
+ )
71
+ }
72
+
73
+ /* -------------------------------------------------------------------------- */
74
+ /* Sections */
75
+ /* -------------------------------------------------------------------------- */
76
+
77
+ /** Trois faits, pas trois slogans. */
78
+ const FAITS = ['Zero configuration', 'TypeScript strict', 'Rechargement a chaud']
79
+
80
+ /** Ce que la fenetre du produit montre. */
81
+ const EXTRAIT = `export function App() {
82
+ return (
83
+ <h1 className="hero-titre">
84
+ Votre premiere page.
85
+ </h1>
86
+ )
87
+ }`
88
+
89
+ /** Une fenetre de navigateur miniature. */
90
+ function Fenetre(): ReactElement {
91
+ return (
92
+ <div className="fenetre">
93
+ <div className="fenetre-barre">
94
+ <span className="fenetre-pastilles" aria-hidden="true">
95
+ <span />
96
+ <span />
97
+ <span />
98
+ </span>
99
+ <span className="fenetre-chemin">src/App.tsx</span>
100
+ </div>
101
+ <pre className="fenetre-code">{EXTRAIT}</pre>
102
+ </div>
103
+ )
104
+ }
105
+
106
+ /** Le hero : la promesse, les actions, et la fenetre du produit. */
107
+ function Hero(): ReactElement {
108
+ return (
109
+ <section className="hero">
110
+ <div className="contenu">
111
+ <span className="pastille-marque">
112
+ <Signe taille="0.9rem" />
113
+ Genere par odoro create
114
+ </span>
115
+
116
+ <h1 className="hero-titre">
117
+ Votre premiere page, <span className="accent">deja vivante</span>.
118
+ </h1>
119
+
120
+ <p className="hero-chapeau">
121
+ Le serveur de developpement, la compilation et le rechargement a chaud
122
+ viennent de <code>odoro</code>. Le systeme de style est le votre.
123
+ </p>
124
+
125
+ <div className="hero-actions">
126
+ <a href="#piliers" className="bouton bouton-primaire">
127
+ Voir ce qui est inclus
128
+ </a>
129
+ <a
130
+ href="https://odoro.dev/docs"
131
+ target="_blank"
132
+ rel="noreferrer"
133
+ className="bouton bouton-secondaire"
134
+ >
135
+ Documentation
136
+ </a>
137
+ </div>
138
+
139
+ <div className="faits">
140
+ {FAITS.map((fait) => (
141
+ <span key={fait} className="fait">
142
+ {fait}
143
+ </span>
144
+ ))}
145
+ </div>
146
+
147
+ <div className="hero-fenetre">
148
+ <Fenetre />
149
+ </div>
150
+ </div>
151
+ </section>
152
+ )
153
+ }
154
+
155
+ /** Ce que le projet a deja sous la main. */
156
+ const PILIERS = [
157
+ {
158
+ titre: 'Compilation',
159
+ texte:
160
+ 'Un serveur de developpement a rechargement a chaud, et une compilation de production.',
161
+ },
162
+ {
163
+ titre: 'TypeScript',
164
+ texte: 'Types stricts, alias de chemins, et verification sans emission.',
165
+ },
166
+ {
167
+ titre: 'A vous de jouer',
168
+ texte: 'Aucun systeme de style impose : le votre prend toute la place.',
169
+ },
170
+ ]
171
+
172
+ /** La section des piliers. */
173
+ function Piliers(): ReactElement {
174
+ return (
175
+ <section id="piliers" className="section">
176
+ <div className="contenu">
177
+ <h2 className="sur-titre">Ce qui est deja la</h2>
178
+ <div className="grille">
179
+ {PILIERS.map((pilier, index) => (
180
+ <article key={pilier.titre} className="carte">
181
+ <span className="carte-numero">{String(index + 1).padStart(2, '0')}</span>
182
+ <h3>{pilier.titre}</h3>
183
+ <p>{pilier.texte}</p>
184
+ </article>
185
+ ))}
186
+ </div>
187
+ </div>
188
+ </section>
189
+ )
190
+ }
191
+
192
+ /** La commande que l'on copie le plus souvent. */
193
+ const COMMANDE = 'npm i @odoro-cli/libs'
194
+
195
+ /** La cloture : une commande, et la porte vers la documentation. */
196
+ function Cloture(): ReactElement {
197
+ const [copie, setCopie] = useState(false)
198
+
199
+ return (
200
+ <section className="section section-centre">
201
+ <div className="contenu-etroit">
202
+ <h2 className="cloture-titre">Ajoutez le systeme de style quand vous voudrez.</h2>
203
+ <p className="cloture-chapeau">
204
+ Les jetons, les utilitaires et les composants vivent dans un paquet a part. Ce
205
+ projet tourne sans eux, et les accueille sans rien casser.
206
+ </p>
207
+
208
+ <div className="commande">
209
+ <code>{COMMANDE}</code>
210
+ <button
211
+ type="button"
212
+ className="bouton bouton-fantome"
213
+ onClick={() => {
214
+ // Le presse-papiers peut etre refuse — hors contexte sur, ou
215
+ // permission retiree. L'echec ne casse pas la page : le libelle
216
+ // ne change simplement pas.
217
+ void navigator.clipboard
218
+ ?.writeText(COMMANDE)
219
+ .then(() => {
220
+ setCopie(true)
221
+ setTimeout(() => {
222
+ setCopie(false)
223
+ }, 1600)
224
+ })
225
+ .catch(() => undefined)
226
+ }}
227
+ >
228
+ {copie ? 'Copie' : 'Copier'}
229
+ </button>
230
+ </div>
231
+
232
+ <a
233
+ href="https://odoro.dev/docs/installation"
234
+ target="_blank"
235
+ rel="noreferrer"
236
+ className="lien-discret"
237
+ >
238
+ Lire la marche a suivre
239
+ </a>
240
+ </div>
241
+ </section>
242
+ )
243
+ }
28
244
 
245
+ /* -------------------------------------------------------------------------- */
246
+ /* Racine */
247
+ /* -------------------------------------------------------------------------- */
248
+
249
+ /** Racine de l'application. */
250
+ export function App(): ReactElement {
251
+ return (
252
+ <div className="app-shell">
253
+ <Barre />
29
254
  <main className="principal">
30
255
  <Fond />
31
256
  <Hero />
32
257
  <Piliers />
33
258
  <Cloture />
34
259
  </main>
35
-
36
260
  <footer className="pied">
37
- <Marque />
261
+ <span className="marque">
262
+ <span className="marque-signe">
263
+ <Signe taille="1.1rem" />
264
+ </span>
265
+ <span className="marque-mot">ODORO</span>
266
+ </span>
38
267
  <span>Construit avec Odoro.</span>
39
268
  </footer>
40
269
  </div>
@@ -5,7 +5,7 @@
5
5
  * degrade, pas une animation.
6
6
  *
7
7
  * Si le moteur a ete retenu, ce fichier est remplace par une version qui ouvre
8
- * une surface WebGL animee.
8
+ * une surface WebGL animee. `App.tsx` place `<Fond />` et n'en demande pas plus.
9
9
  *
10
10
  * @module
11
11
  */
@@ -2,8 +2,8 @@
2
2
 
3
3
  Les bibliotheques Odoro n'ont pas ete retenues a la creation : il n'y a donc
4
4
  ni jetons ni classes utilitaires, et cette feuille porte tout. Le dessin est
5
- celui de la version complete — meme typographie, memes cartes, meme teinte
6
- de marque — en CSS ordinaire.
5
+ celui de la version complete — meme barre en gelules, meme typographie,
6
+ memes cartes, meme teinte de marque — en CSS ordinaire.
7
7
 
8
8
  Une seule variable commande la couleur : `--marque`. La changer repeint le
9
9
  signe, les accents et les boutons d'un seul coup.
@@ -12,7 +12,7 @@
12
12
  `@odoro-cli/libs/styles.css` dans `main.tsx` avant cette feuille. */
13
13
 
14
14
  :root {
15
- --marque: #f97316;
15
+ --marque: #3b82f6;
16
16
  --fond: #ffffff;
17
17
  --encre: #18181b;
18
18
  --doux: #71717a;
@@ -57,54 +57,74 @@ pre {
57
57
  grid-template-rows: auto 1fr auto;
58
58
  }
59
59
 
60
- /* ----- Marque ------------------------------------------------------------- */
61
-
62
- .marque {
63
- display: inline-flex;
64
- align-items: center;
65
- gap: 0.5rem;
66
- font-weight: 600;
67
- letter-spacing: -0.01em;
68
- }
69
-
70
- .marque-signe {
71
- color: var(--marque);
72
- display: inline-flex;
73
- }
60
+ /* ----- Barre en gelules --------------------------------------------------- */
74
61
 
75
- .signe {
76
- width: 1.15em;
77
- height: 1.15em;
78
- }
62
+ /* La barre ne peint pas de bandeau : ce sont les gelules qui portent la
63
+ surface, posees sur ce qu'il y a derriere. Le fond decoratif continue donc
64
+ de passer dessous, au lieu d'etre coupe par une bande opaque. */
79
65
 
80
- /* ----- Coquille ----------------------------------------------------------- */
81
-
82
- .nav {
66
+ .barre {
83
67
  position: sticky;
84
68
  top: 0;
85
69
  z-index: 20;
70
+ padding: 0 1.25rem;
71
+ }
72
+
73
+ .barre-contenu {
86
74
  display: flex;
87
75
  align-items: center;
88
- gap: 1.5rem;
89
- padding: 1rem 1.5rem;
90
- border-bottom: 1px solid var(--filet);
91
- background: color-mix(in oklab, var(--fond) 75%, transparent);
92
- backdrop-filter: blur(10px);
76
+ gap: 0.75rem;
77
+ height: 5rem;
78
+ width: 100%;
79
+ max-width: 64rem;
80
+ margin: 0 auto;
93
81
  }
94
82
 
95
- .nav-lien,
96
- .lien-discret {
83
+ .gelule {
84
+ display: inline-flex;
85
+ align-items: center;
86
+ height: 3.5rem;
87
+ flex-shrink: 0;
88
+ padding: 0 1.25rem;
89
+ border: 1px solid color-mix(in oklab, var(--encre) 12%, transparent);
90
+ border-radius: 9999px;
91
+ background: color-mix(in oklab, var(--fond) 72%, transparent);
92
+ backdrop-filter: blur(16px);
93
+ text-decoration: none;
94
+ }
95
+
96
+ .gelule-lien {
97
97
  margin-left: auto;
98
98
  color: var(--doux);
99
99
  font-size: 0.875rem;
100
- text-decoration: none;
101
100
  }
102
101
 
103
- .nav-lien:hover,
104
- .lien-discret:hover {
102
+ .gelule-lien:hover {
103
+ color: var(--encre);
104
+ }
105
+
106
+ /* ----- Marque ------------------------------------------------------------- */
107
+
108
+ .marque {
109
+ display: inline-flex;
110
+ align-items: center;
111
+ gap: 0.625rem;
112
+ }
113
+
114
+ .marque-signe {
105
115
  color: var(--marque);
116
+ display: inline-flex;
106
117
  }
107
118
 
119
+ .marque-mot {
120
+ font-size: 1.125rem;
121
+ font-weight: 700;
122
+ letter-spacing: 0.025em;
123
+ color: var(--encre);
124
+ }
125
+
126
+ /* ----- Coquille ----------------------------------------------------------- */
127
+
108
128
  .principal {
109
129
  position: relative;
110
130
  }
@@ -120,6 +140,11 @@ pre {
120
140
  font-size: 0.875rem;
121
141
  }
122
142
 
143
+ .pied .marque-mot {
144
+ font-size: 0.875rem;
145
+ color: inherit;
146
+ }
147
+
123
148
  /* ----- Fond decoratif ----------------------------------------------------- */
124
149
 
125
150
  .fond {
@@ -175,7 +200,7 @@ pre {
175
200
  }
176
201
 
177
202
  .hero {
178
- padding: 6rem 1.5rem 5rem;
203
+ padding: 4rem 1.5rem 5rem;
179
204
  }
180
205
 
181
206
  .section {
@@ -193,6 +218,7 @@ pre {
193
218
  display: inline-flex;
194
219
  align-items: center;
195
220
  gap: 0.5rem;
221
+ white-space: nowrap;
196
222
  padding: 0.25rem 0.75rem;
197
223
  border-radius: 9999px;
198
224
  border: 1px solid color-mix(in oklab, var(--marque) 30%, transparent);
@@ -373,6 +399,13 @@ pre {
373
399
  .lien-discret {
374
400
  display: inline-block;
375
401
  margin: 1.5rem auto 0;
402
+ color: var(--doux);
403
+ font-size: 0.875rem;
404
+ text-decoration: none;
405
+ }
406
+
407
+ .lien-discret:hover {
408
+ color: var(--marque);
376
409
  }
377
410
 
378
411
  /* ----- Boutons ------------------------------------------------------------ */