@situaction/traquiste-docs-kit 0.0.0-stage → 1.1.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 (68) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +356 -2
  3. package/client.d.ts +7 -0
  4. package/dist/app/ColorModeContext.d.ts +15 -0
  5. package/dist/app/ColorModeContext.d.ts.map +1 -0
  6. package/dist/app/ColorModeContext.js +58 -0
  7. package/dist/app/config.d.ts +69 -0
  8. package/dist/app/config.d.ts.map +1 -0
  9. package/dist/app/config.js +35 -0
  10. package/dist/app/createDocsApp.d.ts +9 -0
  11. package/dist/app/createDocsApp.d.ts.map +1 -0
  12. package/dist/app/createDocsApp.js +53 -0
  13. package/dist/components/Callout.d.ts +11 -0
  14. package/dist/components/Callout.d.ts.map +1 -0
  15. package/dist/components/Callout.js +28 -0
  16. package/dist/components/CodeBlock.d.ts +12 -0
  17. package/dist/components/CodeBlock.d.ts.map +1 -0
  18. package/dist/components/CodeBlock.js +60 -0
  19. package/dist/components/DeviceFrame.d.ts +17 -0
  20. package/dist/components/DeviceFrame.d.ts.map +1 -0
  21. package/dist/components/DeviceFrame.js +74 -0
  22. package/dist/components/LiveEditor.d.ts +10 -0
  23. package/dist/components/LiveEditor.d.ts.map +1 -0
  24. package/dist/components/LiveEditor.js +231 -0
  25. package/dist/components/PropsTable.d.ts +16 -0
  26. package/dist/components/PropsTable.d.ts.map +1 -0
  27. package/dist/components/PropsTable.js +60 -0
  28. package/dist/components/layout/ComponentSearch.d.ts +2 -0
  29. package/dist/components/layout/ComponentSearch.d.ts.map +1 -0
  30. package/dist/components/layout/ComponentSearch.js +156 -0
  31. package/dist/components/layout/Layout.d.ts +8 -0
  32. package/dist/components/layout/Layout.d.ts.map +1 -0
  33. package/dist/components/layout/Layout.js +109 -0
  34. package/dist/components/layout/NotFound.d.ts +2 -0
  35. package/dist/components/layout/NotFound.d.ts.map +1 -0
  36. package/dist/components/layout/NotFound.js +36 -0
  37. package/dist/components/layout/Sidebar.d.ts +2 -0
  38. package/dist/components/layout/Sidebar.d.ts.map +1 -0
  39. package/dist/components/layout/Sidebar.js +88 -0
  40. package/dist/components/layout/TableOfContents.d.ts +10 -0
  41. package/dist/components/layout/TableOfContents.d.ts.map +1 -0
  42. package/dist/components/layout/TableOfContents.js +48 -0
  43. package/dist/hooks/useCopy.d.ts +5 -0
  44. package/dist/hooks/useCopy.d.ts.map +1 -0
  45. package/dist/hooks/useCopy.js +19 -0
  46. package/dist/index.d.ts +21 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +13 -0
  49. package/dist/pages/DocPage.d.ts +26 -0
  50. package/dist/pages/DocPage.d.ts.map +1 -0
  51. package/dist/pages/DocPage.js +23 -0
  52. package/dist/pages/createComponentPage.d.ts +33 -0
  53. package/dist/pages/createComponentPage.d.ts.map +1 -0
  54. package/dist/pages/createComponentPage.js +150 -0
  55. package/dist/pages/createScreenPage.d.ts +33 -0
  56. package/dist/pages/createScreenPage.d.ts.map +1 -0
  57. package/dist/pages/createScreenPage.js +124 -0
  58. package/dist/styles/docs.css +177 -0
  59. package/dist/styles/pageStyles.d.ts +45 -0
  60. package/dist/styles/pageStyles.d.ts.map +1 -0
  61. package/dist/styles/pageStyles.js +46 -0
  62. package/dist/vite/extractProps.d.ts +8 -0
  63. package/dist/vite/extractProps.d.ts.map +1 -0
  64. package/dist/vite/extractProps.js +79 -0
  65. package/dist/vite/index.d.ts +18 -0
  66. package/dist/vite/index.d.ts.map +1 -0
  67. package/dist/vite/index.js +73 -0
  68. package/package.json +111 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # [1.1.0](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/compare/v1.0.0...v1.1.0) (2026-10-21)
2
+
3
+
4
+ ### Features
5
+
6
+ * statut 'updated' (badge Mis à jour) ([f44dbd3](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/f44dbd354b7d34f3125d57e21c57dbbbcd548b7d))
7
+
8
+ # 1.0.0 (2026-10-20)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * empêcher un contenu large de faire déborder la page ([9a2039e](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/9a2039e9deeeddea8e52f26e2bd7f5161c1ebfce))
14
+ * protéger la doc des styles globaux d'une lib ([82c871a](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/82c871a0e29c6670d17c3b85f1e628c2240a8e29))
15
+
16
+
17
+ ### Features
18
+
19
+ * extraire le moteur de doc de traquiste-mobile ([f9d2316](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/f9d23168b00cb59574ce2d43240b7637dad3d69e))
20
+ * générer les tableaux de props depuis le code (plugin Vite docgen) ([fe0f21c](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/fe0f21cbd10525a580e89095acfdaf7a0af77dba))
21
+ * logo, version en bas de la sidebar et liens dans la barre du haut ([f9b5337](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/f9b5337d431a1ed76c340602f4fbf6f13dd4eccf))
22
+ * mémoriser le mode sombre et suivre la préférence système ([eda9e09](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/eda9e0998f5e7c85681b1bd8270ea0019cd8b67d))
23
+ * navigation — retour en haut, ancres, page 404 et titre d'onglet ([0572519](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/057251978c08baf4face7156f59dd32b4bb8bf9e)), closes [components/button#props](https://bitbucket.org/components/button/issue/props)
24
+ * pages d'écrans complets — createScreenPage et DeviceFrame ([fdb6eb4](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/fdb6eb4ec5526141d766142d14cede48c1130a15))
25
+ * pages de guide — DocPage, DocSection, CodeBlock, Callout et Link ([6c5174a](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/commits/6c5174abf80c2fe9decfad91e7c34a334f7320f2)), closes [#etats](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/issue/etats)
package/README.md CHANGED
@@ -1,3 +1,357 @@
1
- # Temporary Holding Version
1
+ # @situaction/traquiste-docs-kit
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Moteur de site de documentation pour bibliothèques de composants React, partagé par les libs UI Traquiste :
4
+ - [`traq-ui-ste`](https://bitbucket.org/winoc/traq-ui-ste) (web) ;
5
+ - [`traq-ui-ste-mobile`](https://bitbucket.org/winoc/traq-ui-ste-mobile) (React Native, rendu via react-native-web).
6
+
7
+ Chaque lib garde sa propre doc (pages, config, déploiement). Le kit fournit l'outil :
8
+ - la mise en page : sidebar, barre du haut, recherche ⌘K, bascule light / dark, table des matières ;
9
+ - les **pages composant** : titre, statut, lien Figma, ligne d'import, démos live par section, tableau des props ;
10
+ - les **tableaux de props générés** depuis le code TypeScript des composants (plugin Vite `docgen`) ;
11
+ - les **pages de guide** (Prise en main, Theming…) : `DocPage`, `DocSection`, `CodeBlock`, `Callout`, `Link` ;
12
+ - les **pages d'écrans complets** (flux de connexion, back-office…) dans un téléphone ou une fenêtre de navigateur ;
13
+ - l'**éditeur live** (Monaco + Babel) avec copier / reset, redimensionnement et cadre téléphone ;
14
+ - les routes, la sidebar et la recherche, générées depuis la liste des pages ;
15
+ - la navigation : titre d'onglet par page, retour en haut, liens directs vers une ancre, page 404 ;
16
+ - le mode sombre : il suit la préférence système et mémorise le choix du visiteur.
17
+
18
+ ## Installation
19
+
20
+ Dans le dossier de la doc de la lib (en général `docs/`, un projet Vite à part) :
21
+
22
+ ```bash
23
+ npm install -D @situaction/traquiste-docs-kit
24
+ npm install react react-dom
25
+ npm install -D vite @vitejs/plugin-react typescript
26
+ ```
27
+
28
+ | Peer dependency | Version | |
29
+ |---|---|---|
30
+ | `react`, `react-dom` | `^18 \|\| ^19` | obligatoires |
31
+ | `vite` | `6`, `7` ou `8` | le kit est publié en ESM et importe son CSS : la doc doit être construite avec Vite |
32
+ | `typescript` | `>= 5` | nécessaire au plugin `docgen` |
33
+
34
+ `react-router-dom` est fourni par le kit : ne pas l'installer en plus (voir `Link` dans Pages de guide).
35
+
36
+ ## Mise en place
37
+
38
+ ```
39
+ docs/
40
+ index.html
41
+ vite.config.ts
42
+ tsconfig.json
43
+ src/
44
+ main.tsx
45
+ docs.config.tsx
46
+ pages/
47
+ components/button.ts
48
+ guides/GettingStarted.tsx
49
+ ```
50
+
51
+ `index.html` — le site se monte dans `#root`. Le kit ne charge aucune police : c'est à la doc de le faire.
52
+
53
+ ```html
54
+ <!doctype html>
55
+ <html lang="fr">
56
+ <head>
57
+ <meta charset="UTF-8" />
58
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
59
+ <title>traquiste-mobile</title>
60
+ <link href="https://fonts.googleapis.com/css2?family=Urbanist:wght@400;500;600;700&display=swap" rel="stylesheet" />
61
+ </head>
62
+ <body>
63
+ <div id="root"></div>
64
+ <script type="module" src="/src/main.tsx"></script>
65
+ </body>
66
+ </html>
67
+ ```
68
+
69
+ `vite.config.ts` :
70
+
71
+ ```ts
72
+ import { defineConfig } from 'vite'
73
+ import react from '@vitejs/plugin-react'
74
+ import { docgen } from '@situaction/traquiste-docs-kit/vite'
75
+
76
+ export default defineConfig({
77
+ plugins: [
78
+ react(),
79
+ // Chemins relatifs au dossier docs/
80
+ docgen({ include: ['../src/components/**/*.tsx'], tsconfig: '../tsconfig.json' }),
81
+ ],
82
+ })
83
+ ```
84
+
85
+ Les alias propres à une lib restent dans ce fichier : `react-native` → `react-native-web` et stubs côté mobile,
86
+ `sass` côté web…
87
+
88
+ `tsconfig.json` — pour typer le module généré par `docgen` :
89
+
90
+ ```json
91
+ { "compilerOptions": { "types": ["vite/client", "@situaction/traquiste-docs-kit/client"] } }
92
+ ```
93
+
94
+ `src/docs.config.tsx` :
95
+
96
+ ```tsx
97
+ import { defineDocsConfig } from '@situaction/traquiste-docs-kit'
98
+ import { ThemeProvider } from '@situaction/traquiste-mobile'
99
+ import componentProps from 'virtual:traquiste-docs/props'
100
+ import pkg from '../../package.json'
101
+ import GettingStarted from './pages/guides/GettingStarted'
102
+ import ButtonPage from './pages/components/button'
103
+
104
+ export default defineDocsConfig({
105
+ brand: { name: 'traquiste-mobile', subtitle: 'by Situaction', logo: '/logo-situaction.svg', version: pkg.version },
106
+ links: [
107
+ { label: 'npm', href: 'https://www.npmjs.com/package/@situaction/traquiste-mobile' },
108
+ { label: 'Figma', href: 'https://www.figma.com/…' },
109
+ ],
110
+ packageName: '@situaction/traquiste-mobile',
111
+ componentProps,
112
+ // Enveloppe chaque démo live : le thème de la lib suit la bascule light / dark de la doc
113
+ wrapper: ({ mode, children }) => <ThemeProvider colorScheme={mode}>{children}</ThemeProvider>,
114
+ pages: [
115
+ { group: 'Général', label: 'Prise en main', path: '/guides/getting-started', component: GettingStarted },
116
+ { group: 'Composants', label: 'Button', path: '/components/button', component: ButtonPage },
117
+ ],
118
+ })
119
+ ```
120
+
121
+ `pages` donne à la fois les routes, la sidebar (groupes dans l'ordre de première apparition) et la recherche.
122
+ Ajouter une page = un import + une ligne.
123
+
124
+ `src/main.tsx` :
125
+
126
+ ```tsx
127
+ import { createDocsApp } from '@situaction/traquiste-docs-kit'
128
+ import config from './docs.config'
129
+
130
+ createDocsApp(config, document.getElementById('root')!)
131
+ ```
132
+
133
+ Puis `npx vite` pour le serveur de dev, `npx vite build` pour le site statique (à servir avec une redirection de
134
+ toutes les routes vers `index.html` : le site utilise l'historique du navigateur).
135
+
136
+ ## Pages composant
137
+
138
+ ```ts
139
+ import { createComponentPage } from '@situaction/traquiste-docs-kit'
140
+ import { Button } from '@situaction/traquiste-mobile'
141
+
142
+ export default createComponentPage({
143
+ title: 'Button',
144
+ description: "Bouton d'action.",
145
+ status: 'stable',
146
+ figma: 'https://www.figma.com/design/…',
147
+ scope: { Button },
148
+ demos: [
149
+ { section: 'Variantes', title: 'Primary', code: `<Button label="Valider" />` },
150
+ { section: 'Variantes', title: 'Ghost', code: `<Button label="Annuler" variant="ghost" />` },
151
+ { section: 'États', title: 'Désactivé', code: `<Button label="Valider" disabled />` },
152
+ ],
153
+ // Lu dans l'interface TypeScript du composant et ses JSDoc (plugin docgen)
154
+ props: 'auto',
155
+ })
156
+ ```
157
+
158
+ | Option | Description |
159
+ |---|---|
160
+ | `title` | Titre de la page. **C'est aussi le nom du composant** dans la ligne d'import (`import { Button } from '…'`) et pour `props: 'auto'` |
161
+ | `description` | Paragraphe sous le titre |
162
+ | `status` | Badge : `'stable'`, `'beta'`, `'new'` (Nouveau), `'updated'` (Mis à jour), `'deprecated'` (Déprécié) |
163
+ | `figma` | Lien vers le composant Figma (bouton à droite de la description) |
164
+ | `scope` | Ce que le code des démos peut utiliser : composants, hooks, icônes… `React` est injecté d'office |
165
+ | `demos` | Les démos, dans l'ordre (voir ci-dessous) |
166
+ | `props` | `'auto'` (plugin `docgen`) ou tableau écrit à la main : `[{ name, type, required, default?, description }]` |
167
+ | `propsOf` | Composant à lire avec `props: 'auto'` quand il diffère de `title` |
168
+
169
+ Chaque démo :
170
+
171
+ | Champ | Description |
172
+ |---|---|
173
+ | `section` | Titre H2 (ancre et entrée du sommaire), affiché quand il change d'une démo à l'autre |
174
+ | `sectionDescription` | Paragraphe sous ce titre |
175
+ | `title` | En-tête de la carte |
176
+ | `code` | **Une expression JSX**, éditable en direct (voir ci-dessous) |
177
+ | `phoneFrame` | Affiche l'aperçu dans un téléphone, pour les composants pleine largeur |
178
+
179
+ Le code d'une démo est une expression, sans `import` ni instruction au premier niveau. Plusieurs éléments → un
180
+ fragment `<>…</>`. Pour de l'état, créer un composant à la volée :
181
+
182
+ ```jsx
183
+ React.createElement(() => {
184
+ const [on, setOn] = React.useState(false)
185
+ return <Switch value={on} onValueChange={setOn} />
186
+ })
187
+ ```
188
+
189
+ Le JSX est compilé dans le navigateur (preset `react` de Babel) : pas de syntaxe TypeScript dans les démos.
190
+ Une démo qui plante affiche son erreur dans sa carte, sans casser le reste de la page.
191
+
192
+ ## Props générées (plugin `docgen`)
193
+
194
+ Le plugin lit les composants à la compilation et expose `virtual:traquiste-docs/props`
195
+ (`{ [nomDuComposant]: PropDef[] }`), à passer en `componentProps` à `defineDocsConfig`.
196
+
197
+ | Option de `docgen()` | Description |
198
+ |---|---|
199
+ | `include` | Globs des fichiers de composants, relatifs à la racine Vite (ex. `['../src/components/**/*.tsx']`) |
200
+ | `exclude` | Globs à ignorer. Les `*.stories.*`, `*.test.*`, `*.spec.*` et `node_modules` le sont toujours |
201
+ | `tsconfig` | tsconfig de la lib, relatif à la racine Vite. Par défaut : options JSX standard |
202
+
203
+ - Ce qui est lu : nom, type (unions de littéraux développées : `'primary' | 'ghost'`), obligatoire ou non, valeur
204
+ par défaut (déstructuration `variant = 'primary'`), description JSDoc `/** … */`.
205
+ - Les props héritées des types React / React Native (`ButtonHTMLAttributes`, `ViewProps`, `PressableProps`…) sont
206
+ masquées : seule l'API propre au composant apparaît. Pour montrer une prop héritée (par ex. `onPress`), la
207
+ redéclarer dans l'interface du composant avec son JSDoc.
208
+ - Seuls les composants (nom en PascalCase) sont retenus : les constantes et helpers exportés sont ignorés.
209
+ - En dev, modifier un composant met son tableau à jour (rechargement de la page).
210
+ - Si les props d'un composant sont introuvables, la page l'indique avec les points à vérifier au lieu d'afficher
211
+ un tableau vide.
212
+
213
+ ## Pages de guide
214
+
215
+ Pour les pages de texte (Prise en main, Theming, Changelog…), avec le même rendu que les pages composant :
216
+
217
+ ```tsx
218
+ import { Callout, CodeBlock, DocPage, DocSection, Link } from '@situaction/traquiste-docs-kit'
219
+
220
+ export default function GettingStarted() {
221
+ return (
222
+ <DocPage title="Prise en main" description="Installer et configurer la lib.">
223
+ <DocSection title="Installation">
224
+ <p>Installe le package :</p>
225
+ <CodeBlock language="bash">npm install @situaction/traquiste-mobile</CodeBlock>
226
+ <Callout type="warning">Ajoute aussi les peer dependencies.</Callout>
227
+ </DocSection>
228
+ <DocSection title="Theming">
229
+ <p>Voir aussi la page <Link to="/components/button">Button</Link>.</p>
230
+ </DocSection>
231
+ </DocPage>
232
+ )
233
+ }
234
+ ```
235
+
236
+ - `DocPage` : titre, description et **table des matières générée** à partir des `DocSection` (même imbriquées dans
237
+ d'autres composants).
238
+ - `DocSection` : titre H2 et ancre (`États` → `#etats`), avec `id` pour la choisir et `description` pour un chapeau.
239
+ - Le texte écrit en JSX simple (`p`, `h3`, `ul` / `ol`, `a`, `strong`, `code`) est mis en forme automatiquement.
240
+ Les démos insérées dans un guide (`LiveEditor`) gardent leur propre rendu.
241
+ - `CodeBlock` : code statique avec un bouton copier, sans coloration syntaxique. L'indentation commune est
242
+ retirée : on peut écrire le code dans un template literal indenté. `language` ou `title` (par ex. un nom de
243
+ fichier) s'affiche dans l'en-tête.
244
+ - `Callout` : encadré `info` (défaut), `tip`, `warning` ou `danger`, avec `title` facultatif. Ses couleurs suivent
245
+ le thème clair / sombre.
246
+ - `Link` : lien interne sans rechargement. C'est le `Link` de react-router, réexporté pour utiliser le même
247
+ routeur que la doc.
248
+ - `LiveEditor` : une démo live dans une page libre (Exemples, guide) —
249
+ `<LiveEditor title="Formulaire" initialCode={code} scope={{ Button, Input }} />`.
250
+
251
+ ## Écrans complets
252
+
253
+ Pour montrer des écrans entiers construits avec la lib (flux de connexion, liste, formulaire…), un onglet par
254
+ écran :
255
+
256
+ ```tsx
257
+ import { createScreenPage } from '@situaction/traquiste-docs-kit'
258
+
259
+ export default createScreenPage({
260
+ title: 'Flux de connexion',
261
+ description: "Reconstruction du flux d'authentification.",
262
+ device: 'phone', // 'browser' pour la lib web
263
+ screens: [
264
+ {
265
+ label: 'Email',
266
+ description: "Saisie de l'identifiant.",
267
+ components: ['Input', 'Checkbox', 'Button'],
268
+ notes: 'Toute la ligne « Se rappeler de moi » est pressable.',
269
+ component: ScreenEmail,
270
+ },
271
+ // …
272
+ ],
273
+ })
274
+ ```
275
+
276
+ - `device` : `'phone'` (390 × 760 par défaut) ou `'browser'` (1024 × 640, avec `url` affichée dans la barre
277
+ d'adresse, aussi réglable écran par écran). `width` et `height` changent la taille.
278
+ - Chaque écran est rendu dans le `wrapper` de la config : il suit le thème de la lib et le mode clair / sombre.
279
+ Un écran dont la racine a `flex: 1` remplit toute la hauteur de l'appareil ; au-delà, il défile à l'intérieur.
280
+ - L'écran affiché est dans l'URL (`?screen=mot-de-passe`) : on peut donner un lien direct vers un écran.
281
+ - Onglets, flèches du clavier, boutons Précédent / Suivant, et panneau « Écran 2 / 4 » avec description, notes et
282
+ composants utilisés. Un composant qui a une page dans la doc (même `label`) devient un lien vers elle.
283
+ - `DeviceFrame` est exporté pour les pages libres :
284
+ `<DeviceFrame device="browser" url="app.fr" height={600}>…</DeviceFrame>`.
285
+
286
+ ## Thème
287
+
288
+ - **Thème de la lib** : `wrapper` enveloppe chaque démo et chaque écran, `appWrapper` tout le site (pour les pages
289
+ qui utilisent le thème de la lib hors démos). Les deux reçoivent `mode: 'light' | 'dark'`.
290
+ - Les couleurs d'une démo doivent venir du thème de la lib (par ex. `useTheme()` côté mobile, à mettre dans
291
+ `scope`), jamais d'une valeur fixe : sinon elles ne suivent pas la bascule light / dark.
292
+ - `useColorMode()` donne `{ mode, setMode, toggle }` pour les pages qui ont besoin du mode courant.
293
+ - **Police de la doc** : variable CSS `--docs-font-family` (défaut `'Urbanist'`, puis police système), à charger
294
+ dans l'`index.html`.
295
+ - Le CSS de la doc résiste aux styles globaux qu'une lib peut injecter (`:root, body { width: 100vw }`, règles
296
+ `h1`–`h6`).
297
+
298
+ ## Référence de `defineDocsConfig`
299
+
300
+ | Option | Requis | Description |
301
+ |---|---|---|
302
+ | `brand` | oui | `{ name, showName?, subtitle?, logo?, version? }`. En-tête de la sidebar : `logo` (URL d'image, par ex. `/logo-situaction.svg` dans le `public/` de la doc), `name` et `subtitle`. `name` sert aussi au titre des onglets et de texte alternatif au logo. `showName: false` le masque quand le logo contient déjà le nom (sans logo, le nom est toujours affiché). `version` s'affiche en bas de la sidebar |
303
+ | `links` | non | `{ label, href }[]` dans la barre du haut. Les URL `https://…` s'ouvrent dans un nouvel onglet, les chemins (`/examples`) restent dans le site |
304
+ | `packageName` | oui | Package utilisé dans la ligne `import { X } from '…'` des pages composant |
305
+ | `wrapper` | non | Enveloppe chaque démo live et chaque écran, en général le `ThemeProvider` de la lib. Reçoit `mode` |
306
+ | `appWrapper` | non | Enveloppe tout le site. Reçoit `mode` |
307
+ | `componentProps` | non | `import componentProps from 'virtual:traquiste-docs/props'` (plugin `docgen`), pour `props: 'auto'` |
308
+ | `home` | non | Page affichée sur `/`. Par défaut : redirection vers la première page |
309
+ | `pages` | oui | `{ group, label, path, component }[]`, dans l'ordre de la sidebar |
310
+
311
+ ## API exportée
312
+
313
+ `@situaction/traquiste-docs-kit` :
314
+ - `createDocsApp(config, container)` et `DocsApp` (le site sans routeur, pour un montage manuel)
315
+ - `defineDocsConfig`, `useDocsConfig` — types `DocsConfig`, `DocsPage`, `DocsLink`, `DocsWrapper`, `ColorMode`, `NavGroup`, `NavItem`
316
+ - `createComponentPage` — types `ComponentPageConfig`, `Demo`, `PropDef`, `ComponentProps`, `ComponentStatus`
317
+ - `DocPage`, `DocSection`, `CodeBlock`, `Callout`, `Link` — types `DocPageProps`, `DocSectionProps`, `CodeBlockProps`, `CalloutProps`, `CalloutType`
318
+ - `createScreenPage` (types `ScreenPageConfig`, `ScreenConfig`) et `DeviceFrame` (types `DeviceFrameProps`, `DeviceType`)
319
+ - `LiveEditor`
320
+ - `useColorMode` → `{ mode, setMode, toggle }`
321
+
322
+ `@situaction/traquiste-docs-kit/vite` : `docgen(options)` (plugin Vite) et `findComponentFiles`.
323
+
324
+ `@situaction/traquiste-docs-kit/client` : types du module `virtual:traquiste-docs/props`.
325
+
326
+ ## Compatibilité
327
+
328
+ - React 18 et 19 (testé sur les deux en CI). La lib web est en 18, la doc mobile en 19.
329
+ - Vite 6 à 8, TypeScript 5 et plus.
330
+ - Composants React DOM et React Native (via `react-native-web`, alias configuré par la doc de la lib).
331
+ - L'éditeur de code des démos (Monaco) est chargé depuis le CDN jsDelivr à son ouverture.
332
+ - Mise en page prévue pour un écran d'ordinateur.
333
+
334
+ ## Versions
335
+
336
+ Le [CHANGELOG](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/src/master/CHANGELOG.md), aussi publié dans le package, liste les changements de chaque version. Un changement
337
+ incompatible arrive avec une version majeure. Pour monter de version dans une lib :
338
+
339
+ ```bash
340
+ npm install -D @situaction/traquiste-docs-kit@latest
341
+ ```
342
+
343
+ puis vérifier toutes les pages de la doc.
344
+
345
+ ## Contribuer
346
+
347
+ Le code, le playground et la documentation interne du kit (architecture, tests, publication, problèmes connus)
348
+ sont sur [Bitbucket](https://bitbucket.org/winoc/traq-ui-ste-docs-kit), dans le dossier
349
+ [`docs/`](https://bitbucket.org/winoc/traq-ui-ste-docs-kit/src/master/docs/README.md).
350
+
351
+ ```bash
352
+ npm install
353
+ npm run dev # playground sur http://localhost:5173
354
+ npm run typecheck && npm run lint && npm test && npm run build
355
+ ```
356
+
357
+ Licence MIT.
package/client.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /** Types for the module generated by the docgen Vite plugin — reference it from the docs' tsconfig or a .d.ts:
2
+ * /// <reference types="@situaction/traquiste-docs-kit/client" />
3
+ */
4
+ declare module 'virtual:traquiste-docs/props' {
5
+ const componentProps: import('@situaction/traquiste-docs-kit').ComponentProps
6
+ export default componentProps
7
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ColorMode } from './config';
3
+ interface ColorModeContextValue {
4
+ mode: ColorMode;
5
+ toggle: () => void;
6
+ setMode: (mode: ColorMode) => void;
7
+ }
8
+ /** Mode shown on first paint: the visitor's last choice, else the system preference */
9
+ export declare function getInitialColorMode(): ColorMode;
10
+ export declare function ColorModeProvider({ children }: {
11
+ children: ReactNode;
12
+ }): import("react").JSX.Element;
13
+ export declare function useColorMode(): ColorModeContextValue;
14
+ export {};
15
+ //# sourceMappingURL=ColorModeContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorModeContext.d.ts","sourceRoot":"","sources":["../../src/app/ColorModeContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACnC;AAyBD,uFAAuF;AACvF,wBAAgB,mBAAmB,IAAI,SAAS,CAE/C;AAED,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAiCtE;AAED,wBAAgB,YAAY,IAAI,qBAAqB,CAEpD"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Docs-level global color mode state — syncs with data-theme on <html> */
3
+ import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
4
+ const STORAGE_KEY = 'docs-color-mode';
5
+ const DARK_QUERY = '(prefers-color-scheme: dark)';
6
+ const ColorModeContext = createContext({
7
+ mode: 'light',
8
+ toggle: () => { },
9
+ setMode: () => { },
10
+ });
11
+ // Storage can throw (private mode, blocked site data): fall back to the system preference
12
+ function readStoredMode() {
13
+ try {
14
+ const value = localStorage.getItem(STORAGE_KEY);
15
+ return value === 'light' || value === 'dark' ? value : null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ function readSystemMode() {
22
+ return typeof window !== 'undefined' && window.matchMedia?.(DARK_QUERY).matches ? 'dark' : 'light';
23
+ }
24
+ /** Mode shown on first paint: the visitor's last choice, else the system preference */
25
+ export function getInitialColorMode() {
26
+ return readStoredMode() ?? readSystemMode();
27
+ }
28
+ export function ColorModeProvider({ children }) {
29
+ const [storedMode, setStoredMode] = useState(readStoredMode);
30
+ const [systemMode, setSystemMode] = useState(readSystemMode);
31
+ // An explicit choice wins; otherwise follow the OS live
32
+ const mode = storedMode ?? systemMode;
33
+ useEffect(() => {
34
+ const query = window.matchMedia?.(DARK_QUERY);
35
+ if (!query)
36
+ return;
37
+ const onChange = (e) => setSystemMode(e.matches ? 'dark' : 'light');
38
+ query.addEventListener('change', onChange);
39
+ return () => query.removeEventListener('change', onChange);
40
+ }, []);
41
+ useEffect(() => {
42
+ document.documentElement.setAttribute('data-theme', mode);
43
+ }, [mode]);
44
+ const setMode = useCallback((next) => {
45
+ setStoredMode(next);
46
+ try {
47
+ localStorage.setItem(STORAGE_KEY, next);
48
+ }
49
+ catch {
50
+ // Not persisted — the choice still applies for this visit
51
+ }
52
+ }, []);
53
+ const value = useMemo(() => ({ mode, setMode, toggle: () => setMode(mode === 'light' ? 'dark' : 'light') }), [mode, setMode]);
54
+ return _jsx(ColorModeContext.Provider, { value: value, children: children });
55
+ }
56
+ export function useColorMode() {
57
+ return useContext(ColorModeContext);
58
+ }
@@ -0,0 +1,69 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import type { ComponentProps } from '../components/PropsTable';
3
+ export type ColorMode = 'light' | 'dark';
4
+ export interface NavItem {
5
+ label: string;
6
+ path: string;
7
+ }
8
+ export interface NavGroup {
9
+ group: string;
10
+ items: NavItem[];
11
+ }
12
+ /** A docs page: shown in the sidebar under `group`, routed at `path` */
13
+ export interface DocsPage extends NavItem {
14
+ group: string;
15
+ component: ComponentType;
16
+ }
17
+ /** External or internal link shown in the top bar */
18
+ export interface DocsLink {
19
+ label: string;
20
+ /** Absolute URL (opens in a new tab) or in-site path */
21
+ href: string;
22
+ }
23
+ /** Wraps content with the documented library's theme for the current color mode */
24
+ export type DocsWrapper = ComponentType<{
25
+ mode: ColorMode;
26
+ children: ReactNode;
27
+ }>;
28
+ export interface DocsConfig {
29
+ /** Sidebar header */
30
+ brand: {
31
+ /** Library name, e.g. 'traquiste-mobile' — also used in tab titles and as the logo's alt text */
32
+ name: string;
33
+ /** Show the name next to the logo — set false when the logo already contains it (default true) */
34
+ showName?: boolean;
35
+ /** Line under the name, e.g. 'by Situaction' */
36
+ subtitle?: string;
37
+ /** Image URL shown left of the name, e.g. '/logo-situaction.svg' from the docs' public/ folder */
38
+ logo?: string;
39
+ /** Documented version, e.g. the library's package.json version */
40
+ version?: string;
41
+ };
42
+ /** Links in the top bar — the other library's docs, Figma, repository, npm… */
43
+ links?: DocsLink[];
44
+ /** Package used in the generated import snippet of each component page */
45
+ packageName: string;
46
+ /** Wraps every live demo — typically the library's ThemeProvider */
47
+ wrapper?: DocsWrapper;
48
+ /** Wraps the whole site — for pages that use the library's theme outside live demos */
49
+ appWrapper?: DocsWrapper;
50
+ /** Generated props tables: `import componentProps from 'virtual:traquiste-docs/props'` (docgen Vite plugin) */
51
+ componentProps?: ComponentProps;
52
+ /** Page rendered at `/` — defaults to a redirect to the first page */
53
+ home?: ComponentType;
54
+ /** Pages in sidebar order; groups appear in order of first occurrence */
55
+ pages: DocsPage[];
56
+ }
57
+ /** Resolved config: optional wrappers replaced by a pass-through */
58
+ export type ResolvedDocsConfig = DocsConfig & {
59
+ wrapper: DocsWrapper;
60
+ appWrapper: DocsWrapper;
61
+ };
62
+ /** Identity helper — gives type checking and autocompletion in `docs.config.tsx` */
63
+ export declare function defineDocsConfig(config: DocsConfig): DocsConfig;
64
+ export declare function resolveDocsConfig(config: DocsConfig): ResolvedDocsConfig;
65
+ export declare const DocsConfigContext: import("react").Context<ResolvedDocsConfig | null>;
66
+ export declare function useDocsConfig(): ResolvedDocsConfig;
67
+ /** Sidebar / search tree derived from the page list */
68
+ export declare function useNav(): NavGroup[];
69
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/app/config.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;AAExC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,EAAE,CAAA;CACjB;AAED,wEAAwE;AACxE,MAAM,WAAW,QAAS,SAAQ,OAAO;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,aAAa,CAAA;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;CACb;AAED,mFAAmF;AACnF,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC,CAAA;AAEjF,MAAM,WAAW,UAAU;IACzB,qBAAqB;IACrB,KAAK,EAAE;QACL,iGAAiG;QACjG,IAAI,EAAE,MAAM,CAAA;QACZ,kGAAkG;QAClG,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,gDAAgD;QAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,kGAAkG;QAClG,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,kEAAkE;QAClE,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,uFAAuF;IACvF,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,+GAA+G;IAC/G,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,sEAAsE;IACtE,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,yEAAyE;IACzE,KAAK,EAAE,QAAQ,EAAE,CAAA;CAClB;AAED,oEAAoE;AACpE,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,WAAW,CAAA;CAAE,CAAA;AAI/F,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE/D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,kBAAkB,CAMxE;AAED,eAAO,MAAM,iBAAiB,oDAAiD,CAAA;AAE/E,wBAAgB,aAAa,IAAI,kBAAkB,CAIlD;AAED,uDAAuD;AACvD,wBAAgB,MAAM,IAAI,QAAQ,EAAE,CAUnC"}
@@ -0,0 +1,35 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ /** Docs configuration — everything that differs from one library's docs to another */
3
+ import { createContext, useContext, useMemo } from 'react';
4
+ const PassThrough = ({ children }) => _jsx(_Fragment, { children: children });
5
+ /** Identity helper — gives type checking and autocompletion in `docs.config.tsx` */
6
+ export function defineDocsConfig(config) {
7
+ return config;
8
+ }
9
+ export function resolveDocsConfig(config) {
10
+ return {
11
+ ...config,
12
+ wrapper: config.wrapper ?? PassThrough,
13
+ appWrapper: config.appWrapper ?? PassThrough,
14
+ };
15
+ }
16
+ export const DocsConfigContext = createContext(null);
17
+ export function useDocsConfig() {
18
+ const config = useContext(DocsConfigContext);
19
+ if (!config)
20
+ throw new Error('useDocsConfig must be used inside createDocsApp()');
21
+ return config;
22
+ }
23
+ /** Sidebar / search tree derived from the page list */
24
+ export function useNav() {
25
+ const { pages } = useDocsConfig();
26
+ return useMemo(() => {
27
+ const groups = new Map();
28
+ for (const { group, label, path } of pages) {
29
+ if (!groups.has(group))
30
+ groups.set(group, []);
31
+ groups.get(group).push({ label, path });
32
+ }
33
+ return [...groups].map(([group, items]) => ({ group, items }));
34
+ }, [pages]);
35
+ }
@@ -0,0 +1,9 @@
1
+ import type { DocsConfig } from './config';
2
+ import '../styles/docs.css';
3
+ /** Full docs site — use it when you need to mount it yourself (tests, custom router setup) */
4
+ export declare function DocsApp({ config }: {
5
+ config: DocsConfig;
6
+ }): import("react").JSX.Element;
7
+ /** Mounts the docs site into `container` */
8
+ export declare function createDocsApp(config: DocsConfig, container: HTMLElement): void;
9
+ //# sourceMappingURL=createDocsApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createDocsApp.d.ts","sourceRoot":"","sources":["../../src/app/createDocsApp.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,oBAAoB,CAAA;AAsE3B,8FAA8F;AAC9F,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,+BAczD;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,QAUvE"}
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** Docs app entry: providers, layout and routes generated from the config */
3
+ import { StrictMode, useEffect, useMemo } from 'react';
4
+ import { createRoot } from 'react-dom/client';
5
+ import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom';
6
+ import Layout from '../components/layout/Layout';
7
+ import NotFound from '../components/layout/NotFound';
8
+ import { ColorModeProvider, getInitialColorMode, useColorMode } from './ColorModeContext';
9
+ import { DocsConfigContext, resolveDocsConfig, useDocsConfig } from './config';
10
+ import '../styles/docs.css';
11
+ function AppWrapper({ children }) {
12
+ const { appWrapper: Wrapper } = useDocsConfig();
13
+ const { mode } = useColorMode();
14
+ return _jsx(Wrapper, { mode: mode, children: children });
15
+ }
16
+ /** Sets the browser tab title while the page is shown */
17
+ function Titled({ title, children }) {
18
+ useEffect(() => {
19
+ document.title = title;
20
+ }, [title]);
21
+ return _jsx(_Fragment, { children: children });
22
+ }
23
+ /** New page → back to the top, or to the anchor of a deep link (/components/button#props) */
24
+ function ScrollRestoration() {
25
+ const { pathname, hash } = useLocation();
26
+ useEffect(() => {
27
+ const target = hash && document.getElementById(decodeURIComponent(hash.slice(1)));
28
+ // 'instant' bypasses the smooth scroll-behavior set on <html> for in-page anchors:
29
+ // arriving on a page should jump, not animate
30
+ if (target)
31
+ target.scrollIntoView({ behavior: 'instant' });
32
+ else
33
+ window.scrollTo({ top: 0, behavior: 'instant' });
34
+ // Only on page change: in-page anchor clicks are handled natively by the browser
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, [pathname]);
37
+ return null;
38
+ }
39
+ function DocsRoutes() {
40
+ const { pages, home: Home, brand } = useDocsConfig();
41
+ return (_jsxs(Routes, { children: [_jsx(Route, { path: "/", element: Home ? (_jsx(Titled, { title: brand.name, children: _jsx(Home, {}) })) : (_jsx(Navigate, { to: pages[0]?.path ?? '/', replace: true })) }), pages.map(({ path, label, component: Page }) => (_jsx(Route, { path: path, element: _jsx(Titled, { title: `${label} — ${brand.name}`, children: _jsx(Page, {}) }) }, path))), _jsx(Route, { path: "*", element: _jsx(Titled, { title: `Page introuvable — ${brand.name}`, children: _jsx(NotFound, {}) }) })] }));
42
+ }
43
+ /** Full docs site — use it when you need to mount it yourself (tests, custom router setup) */
44
+ export function DocsApp({ config }) {
45
+ const resolved = useMemo(() => resolveDocsConfig(config), [config]);
46
+ return (_jsx(DocsConfigContext.Provider, { value: resolved, children: _jsx(ColorModeProvider, { children: _jsxs(AppWrapper, { children: [_jsx(ScrollRestoration, {}), _jsx(Layout, { children: _jsx(DocsRoutes, {}) })] }) }) }));
47
+ }
48
+ /** Mounts the docs site into `container` */
49
+ export function createDocsApp(config, container) {
50
+ // Apply the theme before React renders, so a dark-mode visitor never sees a light flash
51
+ document.documentElement.setAttribute('data-theme', getInitialColorMode());
52
+ createRoot(container).render(_jsx(StrictMode, { children: _jsx(BrowserRouter, { children: _jsx(DocsApp, { config: config }) }) }));
53
+ }