@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.
- package/CHANGELOG.md +25 -0
- package/README.md +356 -2
- package/client.d.ts +7 -0
- package/dist/app/ColorModeContext.d.ts +15 -0
- package/dist/app/ColorModeContext.d.ts.map +1 -0
- package/dist/app/ColorModeContext.js +58 -0
- package/dist/app/config.d.ts +69 -0
- package/dist/app/config.d.ts.map +1 -0
- package/dist/app/config.js +35 -0
- package/dist/app/createDocsApp.d.ts +9 -0
- package/dist/app/createDocsApp.d.ts.map +1 -0
- package/dist/app/createDocsApp.js +53 -0
- package/dist/components/Callout.d.ts +11 -0
- package/dist/components/Callout.d.ts.map +1 -0
- package/dist/components/Callout.js +28 -0
- package/dist/components/CodeBlock.d.ts +12 -0
- package/dist/components/CodeBlock.d.ts.map +1 -0
- package/dist/components/CodeBlock.js +60 -0
- package/dist/components/DeviceFrame.d.ts +17 -0
- package/dist/components/DeviceFrame.d.ts.map +1 -0
- package/dist/components/DeviceFrame.js +74 -0
- package/dist/components/LiveEditor.d.ts +10 -0
- package/dist/components/LiveEditor.d.ts.map +1 -0
- package/dist/components/LiveEditor.js +231 -0
- package/dist/components/PropsTable.d.ts +16 -0
- package/dist/components/PropsTable.d.ts.map +1 -0
- package/dist/components/PropsTable.js +60 -0
- package/dist/components/layout/ComponentSearch.d.ts +2 -0
- package/dist/components/layout/ComponentSearch.d.ts.map +1 -0
- package/dist/components/layout/ComponentSearch.js +156 -0
- package/dist/components/layout/Layout.d.ts +8 -0
- package/dist/components/layout/Layout.d.ts.map +1 -0
- package/dist/components/layout/Layout.js +109 -0
- package/dist/components/layout/NotFound.d.ts +2 -0
- package/dist/components/layout/NotFound.d.ts.map +1 -0
- package/dist/components/layout/NotFound.js +36 -0
- package/dist/components/layout/Sidebar.d.ts +2 -0
- package/dist/components/layout/Sidebar.d.ts.map +1 -0
- package/dist/components/layout/Sidebar.js +88 -0
- package/dist/components/layout/TableOfContents.d.ts +10 -0
- package/dist/components/layout/TableOfContents.d.ts.map +1 -0
- package/dist/components/layout/TableOfContents.js +48 -0
- package/dist/hooks/useCopy.d.ts +5 -0
- package/dist/hooks/useCopy.d.ts.map +1 -0
- package/dist/hooks/useCopy.js +19 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/pages/DocPage.d.ts +26 -0
- package/dist/pages/DocPage.d.ts.map +1 -0
- package/dist/pages/DocPage.js +23 -0
- package/dist/pages/createComponentPage.d.ts +33 -0
- package/dist/pages/createComponentPage.d.ts.map +1 -0
- package/dist/pages/createComponentPage.js +150 -0
- package/dist/pages/createScreenPage.d.ts +33 -0
- package/dist/pages/createScreenPage.d.ts.map +1 -0
- package/dist/pages/createScreenPage.js +124 -0
- package/dist/styles/docs.css +177 -0
- package/dist/styles/pageStyles.d.ts +45 -0
- package/dist/styles/pageStyles.d.ts.map +1 -0
- package/dist/styles/pageStyles.js +46 -0
- package/dist/vite/extractProps.d.ts +8 -0
- package/dist/vite/extractProps.d.ts.map +1 -0
- package/dist/vite/extractProps.js +79 -0
- package/dist/vite/index.d.ts +18 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +73 -0
- 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
|
-
#
|
|
1
|
+
# @situaction/traquiste-docs-kit
|
|
2
2
|
|
|
3
|
-
|
|
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
|
+
}
|