@hgdc/docs 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/docs.schema.json +21 -0
  2. package/package.json +3 -1
  3. package/src/build/auto-import.ts +5 -24
  4. package/src/build/content.ts +82 -0
  5. package/src/build/markdown.ts +10 -5
  6. package/src/components/Accordion.astro +3 -1
  7. package/src/components/Callout.astro +31 -0
  8. package/src/components/Card.astro +3 -1
  9. package/src/components/Check.astro +2 -3
  10. package/src/components/CodeGroup.astro +9 -1
  11. package/src/components/Danger.astro +2 -3
  12. package/src/components/Info.astro +2 -3
  13. package/src/components/Note.astro +2 -3
  14. package/src/components/Tip.astro +2 -3
  15. package/src/components/Warning.astro +2 -3
  16. package/src/core/components.ts +166 -0
  17. package/src/core/config.ts +42 -0
  18. package/src/core/feedback-api.ts +27 -0
  19. package/src/core/theme.ts +6 -3
  20. package/src/core/validate.ts +276 -0
  21. package/src/integration.ts +102 -30
  22. package/src/overrides/Assistant.astro +17 -39
  23. package/src/overrides/Footer.astro +107 -0
  24. package/src/overrides/Head.astro +14 -14
  25. package/src/overrides/Header.astro +92 -0
  26. package/src/overrides/Icon.astro +65 -0
  27. package/src/overrides/PageFrame.astro +55 -8
  28. package/src/overrides/PageSidebar.astro +7 -0
  29. package/src/overrides/PageTitle.astro +126 -95
  30. package/src/overrides/Search.astro +54 -0
  31. package/src/overrides/Sidebar.astro +105 -60
  32. package/src/overrides/SidebarList.astro +52 -0
  33. package/src/overrides/SiteFooter.astro +51 -0
  34. package/src/overrides/ThemeProvider.astro +23 -0
  35. package/src/overrides/ThemeToggle.astro +90 -0
  36. package/src/overrides/TwoColumnContent.astro +45 -0
  37. package/src/overrides/sections.ts +29 -0
  38. package/src/styles/theme.css +2137 -511
  39. package/src/widget/client.ts +51 -19
  40. package/src/widget/code.ts +218 -0
  41. package/src/widget/excerpt.ts +5 -0
  42. package/src/widget/search.ts +222 -0
  43. package/template/.astro/collections/docs.schema.json +3 -0
  44. package/template/.astro/content-modules.mjs +35 -15
  45. package/template/.astro/data-store.json +1 -0
  46. package/template/.astro/settings.json +5 -0
  47. package/template/.build/.well-known/llms.txt +51 -34
  48. package/template/.build/404.html +16 -42
  49. package/template/.build/_astro/Assistant.astro_astro_type_script_index_0_lang.C1pz7yK1.js +4 -0
  50. package/template/.build/_astro/CodeGroup.astro_astro_type_script_index_0_lang.-eM8maAX.js +1 -0
  51. package/template/.build/_astro/Footer.astro_astro_type_script_index_0_lang.DzCnn3OT.js +1 -0
  52. package/template/.build/_astro/Search.astro_astro_type_script_index_0_lang.D7EcezBU.js +1 -0
  53. package/template/.build/_astro/code.smqv0zhe.js +9 -0
  54. package/template/.build/_astro/common.Dx3aBIS0.css +3 -0
  55. package/template/.build/_astro/{ec.8nqtp.css → ec.t9qpe.css} +1 -1
  56. package/template/.build/_astro/logo.BPu921Tp.svg +1 -0
  57. package/template/.build/_hgdc/corpus.json +1 -1
  58. package/template/.build/concepts/confidentialite/index.html +50 -0
  59. package/template/.build/concepts/confidentialite.md +38 -0
  60. package/template/.build/concepts/deploiements/index.html +106 -0
  61. package/template/.build/concepts/deploiements.md +70 -0
  62. package/template/.build/concepts/organisations-et-roles/index.html +83 -0
  63. package/template/.build/concepts/organisations-et-roles.md +39 -0
  64. package/template/.build/concepts/preversion/index.html +49 -0
  65. package/template/.build/concepts/preversion.md +52 -0
  66. package/template/.build/concepts/secrets-et-coffre/index.html +70 -0
  67. package/template/.build/concepts/secrets-et-coffre.md +54 -0
  68. package/template/.build/demarrer/depuis-github/index.html +34 -0
  69. package/template/.build/demarrer/depuis-github.md +68 -0
  70. package/template/.build/demarrer/premier-site/index.html +28 -0
  71. package/template/.build/demarrer/premier-site.md +94 -0
  72. package/template/.build/guides/brancher-un-domaine/index.html +91 -0
  73. package/template/.build/guides/brancher-un-domaine.md +81 -0
  74. package/template/.build/guides/cle-d-api/index.html +62 -0
  75. package/template/.build/guides/cle-d-api.md +78 -0
  76. package/template/.build/guides/depannage/index.html +64 -0
  77. package/template/.build/guides/depannage.md +69 -0
  78. package/template/.build/guides/deployer-depuis-github/index.html +45 -0
  79. package/template/.build/guides/deployer-depuis-github.md +70 -0
  80. package/template/.build/guides/deployer-un-framework/index.html +81 -0
  81. package/template/.build/guides/deployer-un-framework.md +74 -0
  82. package/template/.build/guides/github-actions-sans-application/index.html +53 -0
  83. package/template/.build/guides/github-actions-sans-application.md +95 -0
  84. package/template/.build/guides/inviter-une-personne/index.html +28 -0
  85. package/template/.build/guides/inviter-une-personne.md +38 -0
  86. package/template/.build/guides/lire-les-logs/index.html +37 -0
  87. package/template/.build/guides/lire-les-logs.md +48 -0
  88. package/template/.build/guides/migrer-depuis-vercel/index.html +25 -0
  89. package/template/.build/guides/migrer-depuis-vercel.md +51 -0
  90. package/template/.build/guides/monorepo/index.html +40 -0
  91. package/template/.build/guides/monorepo.md +42 -0
  92. package/template/.build/guides/revenir-en-arriere/index.html +39 -0
  93. package/template/.build/guides/revenir-en-arriere.md +50 -0
  94. package/template/.build/guides/site-statique/index.html +41 -0
  95. package/template/.build/guides/site-statique.md +59 -0
  96. package/template/.build/guides/synchroniser-doppler/index.html +46 -0
  97. package/template/.build/guides/synchroniser-doppler.md +63 -0
  98. package/template/.build/guides/variables-d-environnement/index.html +73 -0
  99. package/template/.build/guides/variables-d-environnement.md +92 -0
  100. package/template/.build/images/famille/account.svg +1 -0
  101. package/template/.build/images/famille/analytics.svg +1 -0
  102. package/template/.build/images/famille/docs.svg +1 -0
  103. package/template/.build/images/famille/host.svg +1 -0
  104. package/template/.build/images/famille/mail.svg +1 -0
  105. package/template/.build/images/famille/portal.svg +1 -0
  106. package/template/.build/images/famille/status.svg +1 -0
  107. package/template/.build/images/logo.svg +1 -0
  108. package/template/.build/index.html +30 -86
  109. package/template/.build/index.md +59 -21
  110. package/template/.build/llms-full.txt +2330 -518
  111. package/template/.build/llms.txt +51 -34
  112. package/template/.build/pagefind/fragment/fr-ch_16987e2.pf_fragment +0 -0
  113. package/template/.build/pagefind/fragment/fr-ch_2b4c97b.pf_fragment +0 -0
  114. package/template/.build/pagefind/fragment/fr-ch_3294a5c.pf_fragment +0 -0
  115. package/template/.build/pagefind/fragment/fr-ch_34858c9.pf_fragment +0 -0
  116. package/template/.build/pagefind/fragment/fr-ch_39ddba1.pf_fragment +0 -0
  117. package/template/.build/pagefind/fragment/fr-ch_4ab1899.pf_fragment +0 -0
  118. package/template/.build/pagefind/fragment/fr-ch_4d3a52a.pf_fragment +0 -0
  119. package/template/.build/pagefind/fragment/fr-ch_506c187.pf_fragment +0 -0
  120. package/template/.build/pagefind/fragment/fr-ch_5aa255a.pf_fragment +0 -0
  121. package/template/.build/pagefind/fragment/fr-ch_6841c7d.pf_fragment +0 -0
  122. package/template/.build/pagefind/fragment/fr-ch_6dc7a2d.pf_fragment +0 -0
  123. package/template/.build/pagefind/fragment/fr-ch_847edff.pf_fragment +0 -0
  124. package/template/.build/pagefind/fragment/fr-ch_8745af7.pf_fragment +0 -0
  125. package/template/.build/pagefind/fragment/fr-ch_8aac5e6.pf_fragment +0 -0
  126. package/template/.build/pagefind/fragment/fr-ch_916b233.pf_fragment +0 -0
  127. package/template/.build/pagefind/fragment/fr-ch_9fd014a.pf_fragment +0 -0
  128. package/template/.build/pagefind/fragment/fr-ch_a0808f8.pf_fragment +0 -0
  129. package/template/.build/pagefind/fragment/fr-ch_a4e1f69.pf_fragment +0 -0
  130. package/template/.build/pagefind/fragment/fr-ch_a80a53d.pf_fragment +0 -0
  131. package/template/.build/pagefind/fragment/fr-ch_a9e725b.pf_fragment +0 -0
  132. package/template/.build/pagefind/fragment/fr-ch_ac3f64c.pf_fragment +0 -0
  133. package/template/.build/pagefind/fragment/fr-ch_af292f1.pf_fragment +0 -0
  134. package/template/.build/pagefind/fragment/fr-ch_af3e716.pf_fragment +0 -0
  135. package/template/.build/pagefind/fragment/fr-ch_b0689a4.pf_fragment +0 -0
  136. package/template/.build/pagefind/fragment/fr-ch_baed996.pf_fragment +0 -0
  137. package/template/.build/pagefind/fragment/fr-ch_c89e27a.pf_fragment +0 -0
  138. package/template/.build/pagefind/fragment/fr-ch_cd6ca13.pf_fragment +0 -0
  139. package/template/.build/pagefind/fragment/fr-ch_d09af09.pf_fragment +0 -0
  140. package/template/.build/pagefind/fragment/fr-ch_d4bcea8.pf_fragment +0 -0
  141. package/template/.build/pagefind/fragment/fr-ch_dc2a134.pf_fragment +0 -0
  142. package/template/.build/pagefind/fragment/fr-ch_ded7ddc.pf_fragment +0 -0
  143. package/template/.build/pagefind/fragment/fr-ch_e2528cb.pf_fragment +0 -0
  144. package/template/.build/pagefind/fragment/fr-ch_e3cbb4e.pf_fragment +0 -0
  145. package/template/.build/pagefind/fragment/fr-ch_e7902d9.pf_fragment +0 -0
  146. package/template/.build/pagefind/fragment/fr-ch_f48ca47.pf_fragment +0 -0
  147. package/template/.build/pagefind/index/fr-ch_8a5f905.pf_index +0 -0
  148. package/template/.build/pagefind/index/fr-ch_fbd9c96.pf_index +0 -0
  149. package/template/.build/pagefind/pagefind-entry.json +1 -1
  150. package/template/.build/pagefind/pagefind.fr-ch_211aacbfa7f0e.pf_meta +0 -0
  151. package/template/.build/reference/api/deploiements/index.html +326 -0
  152. package/template/.build/reference/api/deploiements.md +170 -0
  153. package/template/.build/reference/api/erreurs/index.html +102 -0
  154. package/template/.build/reference/api/erreurs.md +50 -0
  155. package/template/.build/reference/api/fichiers/index.html +82 -0
  156. package/template/.build/reference/api/fichiers.md +62 -0
  157. package/template/.build/reference/api/introduction/index.html +126 -0
  158. package/template/.build/reference/api/introduction.md +84 -0
  159. package/template/.build/reference/api/projets/index.html +184 -0
  160. package/template/.build/reference/api/projets.md +102 -0
  161. package/template/.build/reference/api/utilisateur/index.html +96 -0
  162. package/template/.build/reference/api/utilisateur.md +89 -0
  163. package/template/.build/reference/api/variables/index.html +75 -0
  164. package/template/.build/reference/api/variables.md +58 -0
  165. package/template/.build/reference/cli/index.html +165 -82
  166. package/template/.build/reference/cli.md +159 -23
  167. package/template/.build/reference/compatibilite/index.html +196 -0
  168. package/template/.build/reference/compatibilite.md +64 -0
  169. package/template/.build/reference/domaines/index.html +171 -0
  170. package/template/.build/reference/domaines.md +76 -0
  171. package/template/.build/reference/limites/index.html +159 -0
  172. package/template/.build/reference/limites.md +56 -0
  173. package/template/.build/reference/variables/index.html +164 -0
  174. package/template/.build/reference/variables.md +63 -0
  175. package/template/.build/reference/vercel-json/index.html +65 -0
  176. package/template/.build/reference/vercel-json.md +51 -0
  177. package/template/node_modules/.vite/deps/_metadata.json +8 -8
  178. package/template/src/content.config.ts +8 -2
  179. package/template/.build/_astro/Assistant.astro_astro_type_script_index_0_lang.DWgmlr85.js +0 -4
  180. package/template/.build/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C3fM4Kra.js +0 -1
  181. package/template/.build/_astro/Search.astro_astro_type_script_index_0_lang.Cn3-p701.js +0 -1
  182. package/template/.build/_astro/TableOfContents.astro_astro_type_script_index_0_lang.BpJaGz7G.js +0 -1
  183. package/template/.build/_astro/common.C-MpX45O.css +0 -3
  184. package/template/.build/_astro/logo-clair.BqNh6JNi.svg +0 -1
  185. package/template/.build/_astro/logo-sombre.BkgsFXxh.svg +0 -1
  186. package/template/.build/_astro/starlight-toc.D4UDIxQL.js +0 -1
  187. package/template/.build/_astro/ui-core.CrG20ya_.js +0 -2
  188. package/template/.build/demarrer/premiere-doc/index.html +0 -84
  189. package/template/.build/demarrer/premiere-doc.md +0 -65
  190. package/template/.build/explications/donnees/index.html +0 -114
  191. package/template/.build/explications/donnees.md +0 -28
  192. package/template/.build/explications/fonctionnement/index.html +0 -93
  193. package/template/.build/explications/fonctionnement.md +0 -32
  194. package/template/.build/guides/agents/index.html +0 -118
  195. package/template/.build/guides/agents.md +0 -54
  196. package/template/.build/guides/assistant/index.html +0 -119
  197. package/template/.build/guides/assistant.md +0 -46
  198. package/template/.build/guides/composants/index.html +0 -97
  199. package/template/.build/guides/composants.md +0 -101
  200. package/template/.build/guides/ecrire/index.html +0 -116
  201. package/template/.build/guides/ecrire.md +0 -63
  202. package/template/.build/guides/navigation/index.html +0 -90
  203. package/template/.build/guides/navigation.md +0 -63
  204. package/template/.build/guides/publier/index.html +0 -95
  205. package/template/.build/guides/publier.md +0 -65
  206. package/template/.build/guides/theme/index.html +0 -87
  207. package/template/.build/guides/theme.md +0 -33
  208. package/template/.build/images/favicon.svg +0 -1
  209. package/template/.build/images/logo-clair.svg +0 -1
  210. package/template/.build/images/logo-sombre.svg +0 -1
  211. package/template/.build/pagefind/fragment/fr-ch_2a431a9.pf_fragment +0 -0
  212. package/template/.build/pagefind/fragment/fr-ch_456586a.pf_fragment +0 -0
  213. package/template/.build/pagefind/fragment/fr-ch_4f8575c.pf_fragment +0 -0
  214. package/template/.build/pagefind/fragment/fr-ch_68e734b.pf_fragment +0 -0
  215. package/template/.build/pagefind/fragment/fr-ch_72b91f4.pf_fragment +0 -0
  216. package/template/.build/pagefind/fragment/fr-ch_8f256dd.pf_fragment +0 -0
  217. package/template/.build/pagefind/fragment/fr-ch_95a15cc.pf_fragment +0 -0
  218. package/template/.build/pagefind/fragment/fr-ch_aa80c55.pf_fragment +0 -0
  219. package/template/.build/pagefind/fragment/fr-ch_ab79738.pf_fragment +0 -0
  220. package/template/.build/pagefind/fragment/fr-ch_cfa4336.pf_fragment +0 -0
  221. package/template/.build/pagefind/fragment/fr-ch_dab8f5e.pf_fragment +0 -0
  222. package/template/.build/pagefind/fragment/fr-ch_de60b43.pf_fragment +0 -0
  223. package/template/.build/pagefind/fragment/fr-ch_e02aa49.pf_fragment +0 -0
  224. package/template/.build/pagefind/fragment/fr-ch_e254a54.pf_fragment +0 -0
  225. package/template/.build/pagefind/fragment/fr-ch_e2c46e3.pf_fragment +0 -0
  226. package/template/.build/pagefind/index/fr-ch_a71411b.pf_index +0 -0
  227. package/template/.build/pagefind/pagefind.fr-ch_2f3ea8fccf961.pf_meta +0 -0
  228. package/template/.build/reference/api-assistant/index.html +0 -161
  229. package/template/.build/reference/api-assistant.md +0 -70
  230. package/template/.build/reference/docs-json/index.html +0 -192
  231. package/template/.build/reference/docs-json.md +0 -43
  232. package/template/.build/reference/mcp/index.html +0 -151
  233. package/template/.build/reference/mcp.md +0 -49
@@ -0,0 +1,107 @@
1
+ ---
2
+ import data from "virtual:hgdc-docs/config"
3
+
4
+ import Icon from "./Icon.astro"
5
+
6
+ // « Cette page t'a aidé ? » au bas de chaque page, envoyé à la console (`/api/v1/feedback`).
7
+ // Sans projet relié, rien n'est affiché : il n'y a personne pour lire les réponses.
8
+ const { pagination } = Astro.locals.starlightRoute
9
+ const endpoint = new URL("/api/v1/feedback", data.config.assistant?.endpoint ?? data.apiEndpoint).toString()
10
+ ---
11
+
12
+ {
13
+ data.config.project && (
14
+ <hgdc-feedback class="hgdc-feedback not-content" data-endpoint={endpoint} data-project={data.config.project} data-pagefind-ignore>
15
+ <div data-step="ask">
16
+ <p class="hgdc-feedback__question">Cette page t'a aidé ?</p>
17
+ <div class="hgdc-feedback__choices">
18
+ <button type="button" data-helpful="true"><Icon name="thumbs-up" size={16} />Oui</button>
19
+ <button type="button" data-helpful="false"><Icon name="thumbs-down" size={16} />Non</button>
20
+ </div>
21
+ </div>
22
+ <form data-step="comment" hidden>
23
+ <label for="hgdc-feedback-comment">Qu'est-ce qui manquait ou pourrait être plus clair ? (facultatif)</label>
24
+ <textarea id="hgdc-feedback-comment" name="comment" rows="3" maxlength="1000"></textarea>
25
+ <div class="hgdc-feedback__choices">
26
+ <button type="submit">Envoyer</button>
27
+ <button type="button" data-skip>Passer</button>
28
+ </div>
29
+ </form>
30
+ <p data-step="done" class="hgdc-feedback__done" role="status" hidden>Merci, c'est noté.</p>
31
+ </hgdc-feedback>
32
+ )
33
+ }
34
+ {
35
+ (pagination.prev || pagination.next) && (
36
+ <nav class="hd-pagination not-content" aria-label="Pages voisines" data-pagefind-ignore>
37
+ {pagination.prev && (
38
+ <a class="hd-pagination__link" href={pagination.prev.href} rel="prev">
39
+ <span class="hd-pagination__hint"><Icon name="chevron-left" size={14} />Précédent</span>
40
+ <span class="hd-pagination__title">{pagination.prev.label}</span>
41
+ </a>
42
+ )}
43
+ {pagination.next && (
44
+ <a class="hd-pagination__link hd-pagination__link--next" href={pagination.next.href} rel="next">
45
+ <span class="hd-pagination__hint">Suivant<Icon name="chevron-right" size={14} /></span>
46
+ <span class="hd-pagination__title">{pagination.next.label}</span>
47
+ </a>
48
+ )}
49
+ </nav>
50
+ )
51
+ }
52
+
53
+ <script>
54
+ import { enhanceContent } from "../widget/code.ts"
55
+
56
+ enhanceContent()
57
+
58
+ class HgdcFeedback extends HTMLElement {
59
+ #helpful: boolean | null = null
60
+
61
+ connectedCallback() {
62
+ for (const button of this.querySelectorAll<HTMLButtonElement>("[data-helpful]"))
63
+ button.addEventListener("click", () => this.#choose(button.dataset.helpful === "true"))
64
+ const form = this.querySelector("form")!
65
+ form.addEventListener("submit", (event) => {
66
+ event.preventDefault()
67
+ const comment = new FormData(form).get("comment")
68
+ void this.#send(typeof comment === "string" ? comment.trim() : "")
69
+ })
70
+ this.querySelector("[data-skip]")?.addEventListener("click", () => void this.#send(""))
71
+ }
72
+
73
+ #show(step: "ask" | "comment" | "done") {
74
+ for (const element of this.querySelectorAll<HTMLElement>("[data-step]")) element.hidden = element.dataset.step !== step
75
+ if (step === "comment") this.querySelector("textarea")?.focus()
76
+ }
77
+
78
+ #choose(helpful: boolean) {
79
+ this.#helpful = helpful
80
+ // Un oui part tout de suite ; un non attend le commentaire (ou « Passer ») : un seul envoi par avis.
81
+ if (helpful) void this.#send("")
82
+ else this.#show("comment")
83
+ }
84
+
85
+ async #send(comment: string) {
86
+ if (this.#helpful === null) return
87
+ try {
88
+ await fetch(this.dataset.endpoint!, {
89
+ method: "POST",
90
+ headers: { "content-type": "application/json" },
91
+ body: JSON.stringify({
92
+ project: this.dataset.project,
93
+ page: location.pathname,
94
+ helpful: this.#helpful,
95
+ ...(comment ? { comment } : {}),
96
+ }),
97
+ keepalive: true,
98
+ })
99
+ } catch {
100
+ // Un retour perdu ne gêne pas la lecture : rien à afficher.
101
+ }
102
+ this.#show("done")
103
+ }
104
+ }
105
+ customElements.define("hgdc-feedback", HgdcFeedback)
106
+ </script>
107
+
@@ -1,14 +1,14 @@
1
- ---
2
- import Default from "@astrojs/starlight/components/Head.astro"
3
- import data from "virtual:hgdc-docs/config"
4
-
5
- import { markdownPath } from "../core/llms.ts"
6
- import { withBase, withoutBase } from "../core/navigation.ts"
7
-
8
- // llmstxt.org : chaque page annonce sa version Markdown et l'index qui la décrit.
9
- const markdown = withBase(data.base, markdownPath(withoutBase(data.base, Astro.url.pathname)))
10
- ---
11
-
12
- <Default><slot /></Default>
13
- <link rel="alternate" type="text/markdown" href={markdown} />
14
- <link rel="describedby" type="text/markdown" href={withBase(data.base, "/llms.txt")} />
1
+ ---
2
+ import Default from "@astrojs/starlight/components/Head.astro"
3
+ import data from "virtual:hgdc-docs/config"
4
+
5
+ import { markdownPath } from "../core/llms.ts"
6
+ import { withBase, withoutBase } from "../core/navigation.ts"
7
+
8
+ // llmstxt.org : chaque page annonce sa version Markdown et l'index qui la décrit.
9
+ const markdown = withBase(data.base, markdownPath(withoutBase(data.base, Astro.url.pathname)))
10
+ ---
11
+
12
+ <Default><slot /></Default>
13
+ <link rel="alternate" type="text/markdown" href={markdown} />
14
+ <link rel="describedby" type="text/markdown" href={withBase(data.base, "/llms.txt")} />
@@ -0,0 +1,92 @@
1
+ ---
2
+ import Search from "virtual:starlight/components/Search"
3
+ import data from "virtual:hgdc-docs/config"
4
+
5
+ import { assistantEnabled, docsSections, sectionHref } from "./sections.ts"
6
+ import Icon from "./Icon.astro"
7
+ import ThemeToggle from "./ThemeToggle.astro"
8
+
9
+ /**
10
+ * En-tête, comme chez Mintlify : produit à gauche, onglets de docs.json au centre, puis la
11
+ * recherche, l'assistant, les liens de `navbar` et le thème. Sur téléphone, le menu, le
12
+ * produit, la recherche et l'assistant seulement : le reste passe dans le menu.
13
+ */
14
+ const { tabs, current } = docsSections(data.tree, Astro.locals.hgdcSection ?? 0)
15
+ const home = `${data.base}/`
16
+ const logo = typeof data.config.logo === "string" ? { light: data.config.logo } : data.config.logo
17
+ const src = (path: string) => `${data.base}${path.startsWith("/") ? path : `/${path}`}`
18
+ const links = data.config.navbar?.links ?? []
19
+ const primary = data.config.navbar?.primary
20
+ const assistant = assistantEnabled(data.config)
21
+ ---
22
+
23
+ <div class="hd-header">
24
+ <div class="hd-header__start">
25
+ <button
26
+ type="button"
27
+ class="hd-icon-button hd-menu-button"
28
+ popovertarget="starlight__sidebar"
29
+ aria-label="Menu de la documentation"
30
+ aria-controls="starlight__sidebar"
31
+ >
32
+ <Icon name="menu" />
33
+ </button>
34
+ <a class="hd-brand" href={logo?.href ?? home}>
35
+ {
36
+ logo && (
37
+ <span class="hd-brand__mark">
38
+ <img class="hd-brand__light" src={src(logo.light)} alt="" width="24" height="24" />
39
+ <img class="hd-brand__dark" src={src(logo.dark ?? logo.light)} alt="" width="24" height="24" />
40
+ </span>
41
+ )
42
+ }
43
+ <span class="hd-brand__name">{data.config.name}</span>
44
+ </a>
45
+ </div>
46
+
47
+ {
48
+ tabs.length > 1 && (
49
+ <nav class="hd-header__tabs" aria-label="Sections de la documentation">
50
+ {tabs.map((tab) => (
51
+ <a href={sectionHref(data.base, tab.items)} aria-current={tab === current.tab ? "page" : undefined}>
52
+ {tab.label}
53
+ </a>
54
+ ))}
55
+ </nav>
56
+ )
57
+ }
58
+
59
+ <div class="hd-header__end">
60
+ <Search />
61
+ {
62
+ assistant && (
63
+ <button
64
+ type="button"
65
+ class="hd-icon-button"
66
+ data-hgdc-ask
67
+ aria-label="Demander à l'assistant"
68
+ title="Demander à l'assistant (Ctrl I)"
69
+ >
70
+ <Icon name="sparkles" />
71
+ </button>
72
+ )
73
+ }
74
+ {
75
+ (links.length > 0 || primary) && (
76
+ <nav class="hd-header__links" aria-label="Liens">
77
+ {links.map((link) => (
78
+ <a class="hd-pill hd-pill--ghost" href={link.href}>
79
+ {link.label}
80
+ </a>
81
+ ))}
82
+ {primary && (
83
+ <a class="hd-pill hd-pill--primary" href={primary.href}>
84
+ {primary.label}
85
+ </a>
86
+ )}
87
+ </nav>
88
+ )
89
+ }
90
+ <ThemeToggle variant="button" />
91
+ </div>
92
+ </div>
@@ -0,0 +1,65 @@
1
+ ---
2
+ /**
3
+ * Icônes du modèle, au trait (24 × 24, 1,75), dessinées en ligne : aucune requête, aucune
4
+ * police d'icônes. `currentColor` suit le texte.
5
+ */
6
+ const PATHS = {
7
+ menu: "M4 7h16M4 12h16M4 17h10",
8
+ search: "M11 18a7 7 0 1 0 0-14 7 7 0 0 0 0 14Zm5-2 4 4",
9
+ sparkles:
10
+ "M12 3.5 13.6 8a3 3 0 0 0 1.9 1.9L20 11.5l-4.5 1.6a3 3 0 0 0-1.9 1.9L12 19.5 10.4 15a3 3 0 0 0-1.9-1.9L4 11.5 8.5 9.9A3 3 0 0 0 10.4 8ZM19 3v3M20.5 4.5h-3",
11
+ sun: "M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM12 2.5v2M12 19.5v2M4.6 4.6 6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4 6 18M18 6l1.4-1.4",
12
+ moon: "M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5Z",
13
+ monitor: "M4 5h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Zm4 15h8m-4-3v3",
14
+ copy: "M9 9h10a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1Zm-4 6H4.5A1.5 1.5 0 0 1 3 13.5v-9A1.5 1.5 0 0 1 4.5 3h9A1.5 1.5 0 0 1 15 4.5V5",
15
+ check: "m5 12.5 4.5 4.5L19 7.5",
16
+ "chevron-down": "m6 9 6 6 6-6",
17
+ "chevron-right": "m9 6 6 6-6 6",
18
+ "chevron-left": "m15 6-6 6 6 6",
19
+ "arrow-up": "M12 19V5m-6 6 6-6 6 6",
20
+ "arrow-right": "M5 12h14m-6-6 6 6-6 6",
21
+ "arrow-up-right": "M7 17 17 7M8 7h9v9",
22
+ x: "M6 6l12 12M18 6 6 18",
23
+ flag: "M12 8v4.5M12 16h.01M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z",
24
+ list: "M4 6h16M4 12h10M4 18h13",
25
+ "thumbs-up":
26
+ "M7 10v11M15 5.9 14 10h5.8a2 2 0 0 1 1.9 2.5l-2.3 7A2 2 0 0 1 17.5 21H4a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1h2.8a2 2 0 0 0 1.8-1.1L12 2a3.1 3.1 0 0 1 3 3.9Z",
27
+ "thumbs-down":
28
+ "M17 14V3M9 18.1 10 14H4.2a2 2 0 0 1-1.9-2.5l2.3-7A2 2 0 0 1 6.5 3H20a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1h-2.8a2 2 0 0 0-1.8 1.1L12 22a3.1 3.1 0 0 1-3-3.9Z",
29
+ info: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0-5v-4.5m0-3.5h.01",
30
+ note: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0-5v-4.5m0-3.5h.01",
31
+ tip: "M9 18h6m-5 3h4M12 3a6 6 0 0 0-3.6 10.8c.5.4.6.8.6 1.2v.5h6V15c0-.4.2-.8.6-1.2A6 6 0 0 0 12 3Z",
32
+ warning: "M12 9.5v4M12 17h.01M10.3 4.2 2.6 17.5A2 2 0 0 0 4.3 20.5h15.4a2 2 0 0 0 1.7-3L13.7 4.2a2 2 0 0 0-3.4 0Z",
33
+ danger: "M12 8v4.5M12 16h.01M8.3 3h7.4L21 8.3v7.4L15.7 21H8.3L3 15.7V8.3Z",
34
+ "circle-check": "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm-4-9 2.8 2.8L16 9.5",
35
+ file: "M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8Zm0 0v5h5M9 13h6m-6 4h4",
36
+ hash: "M5 9h14M5 15h14M10 4 8 20M16 4l-2 16",
37
+ rotate: "M4 12a8 8 0 1 0 2.3-5.7M4 4v4h4",
38
+ expand: "M15 4h5v5M9 20H4v-5M20 4l-6 6M4 20l6-6",
39
+ shrink: "M14 10h6M14 10V4M10 14H4m6 0v6M14 10l6-6M10 14l-6 6",
40
+ markdown: "M4 6h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm3 9V9l2.5 3L12 9v6m5-6v6m-2-2 2 2 2-2",
41
+ external: "M14 4h6v6M20 4l-9 9M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4",
42
+ } as const
43
+
44
+ export type IconName = keyof typeof PATHS
45
+
46
+ interface Props {
47
+ name: IconName
48
+ size?: number
49
+ class?: string
50
+ }
51
+ const { name, size = 18, class: className } = Astro.props
52
+ ---
53
+
54
+ <svg
55
+ class:list={["hd-icon", className]}
56
+ aria-hidden="true"
57
+ viewBox="0 0 24 24"
58
+ width={size}
59
+ height={size}
60
+ fill="none"
61
+ stroke="currentColor"
62
+ stroke-width="1.75"
63
+ stroke-linecap="round"
64
+ stroke-linejoin="round"><path d={PATHS[name]}></path></svg
65
+ >
@@ -1,15 +1,62 @@
1
1
  ---
2
- import Default from "@astrojs/starlight/components/PageFrame.astro"
3
2
  import data from "virtual:hgdc-docs/config"
4
3
 
5
4
  import Assistant from "./Assistant.astro"
5
+ import { assistantEnabled } from "./sections.ts"
6
+ import SiteFooter from "./SiteFooter.astro"
6
7
 
7
- const assistant = data.config.project && data.config.assistant?.enabled !== false
8
+ /**
9
+ * Cadre de page. En-tête fixe ; barre latérale fixe à gauche, jusqu'en bas de la page ;
10
+ * à droite, le contenu puis le pied de page, qui ne passe jamais sous la barre. Ouvert,
11
+ * l'assistant prend une colonne à droite et pousse le contenu au lieu de le recouvrir.
12
+ */
13
+ const { hasSidebar } = Astro.locals.starlightRoute
14
+ const assistant = assistantEnabled(data.config)
8
15
  ---
9
16
 
10
- <Default>
11
- <slot name="header" slot="header" />
12
- <slot name="sidebar" slot="sidebar" />
13
- <slot />
14
- </Default>
15
- {assistant && <Assistant />}
17
+ <div class="hd-page">
18
+ <header class="hd-topbar"><slot name="header" /></header>
19
+ {
20
+ hasSidebar && (
21
+ <nav class="hd-sidebar" aria-label="Navigation de la documentation">
22
+ <hd-sidebar-pane popover="auto" id="starlight__sidebar" class="sidebar-pane">
23
+ <div class="hd-sidebar__content">
24
+ <slot name="sidebar" />
25
+ </div>
26
+ </hd-sidebar-pane>
27
+ </nav>
28
+ )
29
+ }
30
+ <div class="hd-main-frame main-frame">
31
+ <slot />
32
+ <SiteFooter />
33
+ </div>
34
+ {assistant && <Assistant />}
35
+ </div>
36
+
37
+ <script>
38
+ // Le menu de téléphone est un popover : il s'ouvre sans JavaScript. Ce script le retire
39
+ // sur ordinateur, où la barre est toujours visible, et rend le reste inerte quand il est ouvert.
40
+ class SidebarPane extends HTMLElement {
41
+ connectedCallback() {
42
+ const desktop = matchMedia("(min-width: 50em)")
43
+ const reset = () => {
44
+ if (desktop.matches && this.matches(":popover-open")) this.hidePopover()
45
+ this.popover = desktop.matches ? null : "auto"
46
+ }
47
+ reset()
48
+ desktop.addEventListener("change", reset)
49
+ this.addEventListener("toggle", (event) => {
50
+ const open = (event as ToggleEvent).newState === "open"
51
+ for (const element of document.querySelectorAll<HTMLElement>(".hd-main-frame, .hd-askbar"))
52
+ element.toggleAttribute("inert", open)
53
+ document.documentElement.toggleAttribute("data-hd-menu", open)
54
+ })
55
+ // Un lien suivi dans le menu le ferme (utile pour une ancre de la même page).
56
+ this.addEventListener("click", (event) => {
57
+ if ((event.target as HTMLElement).closest("a") && this.matches(":popover-open")) this.hidePopover()
58
+ })
59
+ }
60
+ }
61
+ customElements.define("hd-sidebar-pane", SidebarPane)
62
+ </script>
@@ -0,0 +1,7 @@
1
+ ---
2
+ import TableOfContents from "virtual:starlight/components/TableOfContents"
3
+
4
+ // Table des matières seule : sur téléphone, comme chez Mintlify, la page se lit sans elle.
5
+ ---
6
+
7
+ {Astro.locals.starlightRoute.toc && <TableOfContents />}
@@ -1,95 +1,126 @@
1
- ---
2
- import Default from "@astrojs/starlight/components/PageTitle.astro"
3
- import data from "virtual:hgdc-docs/config"
4
-
5
- import { markdownPath } from "../core/llms.ts"
6
- import { withBase, withoutBase } from "../core/navigation.ts"
7
-
8
- const markdown = withBase(data.base, markdownPath(withoutBase(data.base, Astro.url.pathname)))
9
- const assistant = Boolean(data.config.project) && data.config.assistant?.enabled !== false
10
- ---
11
-
12
- <div class="hgdc-title">
13
- <Default><slot /></Default>
14
- <div class="hgdc-page-actions not-content" data-hgdc-skip data-pagefind-ignore>
15
- <button type="button" class="hgdc-action" data-hgdc-copy={markdown}>
16
- <svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16"
17
- ><rect x="8" y="8" width="12" height="12" rx="3" fill="none" stroke="currentColor" stroke-width="1.8"
18
- ></rect><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2" fill="none" stroke="currentColor" stroke-width="1.8"
19
- ></path></svg
20
- >
21
- <span data-label>Copier pour un LLM</span>
22
- </button>
23
- <details class="hgdc-menu">
24
- <summary class="hgdc-action hgdc-action--icon" aria-label="Autres formats de la page">
25
- <svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16"
26
- ><path d="m6 9 6 6 6-6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path></svg
27
- >
28
- </summary>
29
- <ul class="hgdc-menu__list">
30
- <li><a href={markdown}>Voir en Markdown</a></li>
31
- <li><a data-hgdc-open="claude" href="https://claude.ai/new" target="_blank" rel="noopener">Ouvrir dans Claude</a></li>
32
- <li><a data-hgdc-open="chatgpt" href="https://chatgpt.com/" target="_blank" rel="noopener">Ouvrir dans ChatGPT</a></li>
33
- <li><a href={withBase(data.base, "/llms.txt")}>Index pour les agents (llms.txt)</a></li>
34
- </ul>
35
- </details>
36
- {
37
- assistant && (
38
- <button type="button" class="hgdc-action" data-hgdc-ask>
39
- <svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16">
40
- <path d="M12 3l1.9 4.6L18.5 9.5l-4.6 1.9L12 16l-1.9-4.6L5.5 9.5l4.6-1.9z" fill="currentColor" />
41
- </svg>
42
- <span>Demander à l'assistant</span>
43
- </button>
44
- )
45
- }
46
- <span class="sr-only" role="status" aria-live="polite" data-hgdc-copy-status></span>
47
- </div>
48
- </div>
49
-
50
- <script>
51
- const status = document.querySelector<HTMLElement>("[data-hgdc-copy-status]")
52
-
53
- for (const button of document.querySelectorAll<HTMLButtonElement>("[data-hgdc-copy]")) {
54
- const label = button.querySelector<HTMLElement>("[data-label]")!
55
- button.addEventListener("click", async () => {
56
- const done = (text: string) => {
57
- label.textContent = text
58
- if (status) status.textContent = text
59
- setTimeout(() => (label.textContent = "Copier pour un LLM"), 2000)
60
- }
61
- try {
62
- const response = await fetch(button.dataset.hgdcCopy!)
63
- if (!response.ok) throw new Error(String(response.status))
64
- await navigator.clipboard.writeText(await response.text())
65
- done("Page copiée")
66
- } catch {
67
- done("Copie impossible")
68
- }
69
- })
70
- }
71
-
72
- // « Ouvrir dans… » : l'assistant externe lit la version Markdown de cette page.
73
- const markdownUrl = new URL(document.querySelector<HTMLElement>("[data-hgdc-copy]")!.dataset.hgdcCopy!, location.href)
74
- const prompt = `Lis ${markdownUrl.href} et réponds à mes questions sur cette page.`
75
- for (const link of document.querySelectorAll<HTMLAnchorElement>("[data-hgdc-open]")) {
76
- const base = link.dataset.hgdcOpen === "claude" ? "https://claude.ai/new" : "https://chatgpt.com/"
77
- link.href = `${base}?q=${encodeURIComponent(prompt)}`
78
- }
79
-
80
- // Le menu se ferme au clic extérieur et à Échap, comme un menu natif.
81
- for (const menu of document.querySelectorAll<HTMLDetailsElement>(".hgdc-menu")) {
82
- document.addEventListener("click", (event) => {
83
- if (menu.open && !menu.contains(event.target as Node)) menu.open = false
84
- })
85
- menu.addEventListener("keydown", (event) => {
86
- if (event.key === "Escape" && menu.open) {
87
- menu.open = false
88
- menu.querySelector("summary")?.focus()
89
- }
90
- })
91
- }
92
-
93
- for (const button of document.querySelectorAll("[data-hgdc-ask]"))
94
- button.addEventListener("click", () => document.dispatchEvent(new CustomEvent("hgdc:assistant-open")))
95
- </script>
1
+ ---
2
+ import type { StarlightRouteData } from "@astrojs/starlight/route-data"
3
+ import data from "virtual:hgdc-docs/config"
4
+
5
+ import { markdownPath } from "../core/llms.ts"
6
+ import { withBase, withoutBase } from "../core/navigation.ts"
7
+ import Icon from "./Icon.astro"
8
+
9
+ /**
10
+ * En-tête de page : le groupe en surtitre, le titre, la description de la page en chapeau,
11
+ * et « Copier la page » avec ses autres formats (Markdown, Claude, ChatGPT, llms.txt).
12
+ */
13
+ type Entry = StarlightRouteData["sidebar"][number]
14
+ const route = Astro.locals.starlightRoute
15
+ const containsCurrent = (entry: Entry): boolean =>
16
+ entry.type === "link" ? entry.isCurrent : entry.entries.some(containsCurrent)
17
+ const group = route.sidebar.find((entry) => entry.type === "group" && containsCurrent(entry))?.label
18
+ const description = route.entry.data.description
19
+ const markdown = withBase(data.base, markdownPath(withoutBase(data.base, Astro.url.pathname)))
20
+ ---
21
+
22
+ <div class="hd-title not-content">
23
+ {group && <p class="hd-eyebrow" data-pagefind-meta="section">{group}</p>}
24
+ <div class="hd-title__row">
25
+ <h1 id="_top">{route.entry.data.title}</h1>
26
+ <div class="hd-page-actions" data-hgdc-skip data-pagefind-ignore>
27
+ <div class="hd-split">
28
+ <button type="button" class="hd-split__main" data-hgdc-copy={markdown}>
29
+ <Icon name="copy" size={16} />
30
+ <span data-label>Copier la page</span>
31
+ </button>
32
+ <details class="hd-menu">
33
+ <summary class="hd-split__more" aria-label="Autres formats de la page">
34
+ <Icon name="chevron-down" size={16} />
35
+ </summary>
36
+ <ul class="hd-menu__list">
37
+ <li>
38
+ <button type="button" data-hgdc-copy-item>
39
+ <Icon name="copy" />
40
+ <span><strong>Copier la page</strong><small>En Markdown, pour un LLM</small></span>
41
+ </button>
42
+ </li>
43
+ <li>
44
+ <a href={markdown}>
45
+ <Icon name="markdown" />
46
+ <span><strong>Voir en Markdown</strong><small>La page en texte brut</small></span>
47
+ </a>
48
+ </li>
49
+ <li>
50
+ <a data-hgdc-open="claude" href="https://claude.ai/new" target="_blank" rel="noopener">
51
+ <Icon name="arrow-up-right" />
52
+ <span><strong>Ouvrir dans Claude</strong><small>Poser une question sur cette page</small></span>
53
+ </a>
54
+ </li>
55
+ <li>
56
+ <a data-hgdc-open="chatgpt" href="https://chatgpt.com/" target="_blank" rel="noopener">
57
+ <Icon name="arrow-up-right" />
58
+ <span><strong>Ouvrir dans ChatGPT</strong><small>Poser une question sur cette page</small></span>
59
+ </a>
60
+ </li>
61
+ <li>
62
+ <a href={withBase(data.base, "/llms.txt")}>
63
+ <Icon name="file" />
64
+ <span><strong>llms.txt</strong><small>L'index de la doc pour les agents</small></span>
65
+ </a>
66
+ </li>
67
+ </ul>
68
+ </details>
69
+ </div>
70
+ <span class="sr-only" role="status" aria-live="polite" data-hgdc-copy-status></span>
71
+ </div>
72
+ </div>
73
+ {description && <p class="hd-lead">{description}</p>}
74
+ </div>
75
+
76
+ <script>
77
+ const status = document.querySelector<HTMLElement>("[data-hgdc-copy-status]")
78
+ const main = document.querySelector<HTMLButtonElement>("[data-hgdc-copy]")
79
+
80
+ async function copyPage() {
81
+ if (!main) return
82
+ const label = main.querySelector<HTMLElement>("[data-label]")!
83
+ const done = (text: string) => {
84
+ label.textContent = text
85
+ if (status) status.textContent = text
86
+ setTimeout(() => (label.textContent = "Copier la page"), 2000)
87
+ }
88
+ try {
89
+ const response = await fetch(main.dataset.hgdcCopy!)
90
+ if (!response.ok) throw new Error(String(response.status))
91
+ await navigator.clipboard.writeText(await response.text())
92
+ done("Page copiée")
93
+ } catch {
94
+ done("Copie impossible")
95
+ }
96
+ }
97
+ main?.addEventListener("click", () => void copyPage())
98
+ document.querySelector("[data-hgdc-copy-item]")?.addEventListener("click", () => {
99
+ document.querySelector<HTMLDetailsElement>(".hd-menu")!.open = false
100
+ void copyPage()
101
+ })
102
+
103
+ // « Ouvrir dans… » : l'assistant externe lit la version Markdown de cette page.
104
+ if (main) {
105
+ const markdownUrl = new URL(main.dataset.hgdcCopy!, location.href)
106
+ const prompt = `Lis ${markdownUrl.href} et réponds à mes questions sur cette page.`
107
+ for (const link of document.querySelectorAll<HTMLAnchorElement>("[data-hgdc-open]")) {
108
+ const base = link.dataset.hgdcOpen === "claude" ? "https://claude.ai/new" : "https://chatgpt.com/"
109
+ link.href = `${base}?q=${encodeURIComponent(prompt)}`
110
+ }
111
+ }
112
+
113
+ // Le menu se ferme au clic extérieur et à Échap, comme un menu natif.
114
+ for (const menu of document.querySelectorAll<HTMLDetailsElement>(".hd-menu")) {
115
+ document.addEventListener("click", (event) => {
116
+ if (menu.open && !menu.contains(event.target as Node)) menu.open = false
117
+ })
118
+ menu.addEventListener("keydown", (event) => {
119
+ if (event.key === "Escape" && menu.open) {
120
+ event.stopPropagation()
121
+ menu.open = false
122
+ menu.querySelector("summary")?.focus()
123
+ }
124
+ })
125
+ }
126
+ </script>