@docsector/docsector-reader 2.3.0 → 3.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 (294) hide show
  1. package/README.md +50 -21
  2. package/bin/docsector.js +1 -1
  3. package/package.json +5 -3
  4. package/src/components/DMenu.vue +15 -8
  5. package/src/components/DPage.vue +99 -5
  6. package/src/components/DPageExpandable.vue +78 -0
  7. package/src/components/DPageSection.vue +7 -572
  8. package/src/components/DPageSourceCode.vue +1 -1
  9. package/src/components/DPageTokens.vue +122 -0
  10. package/src/components/DSubpage.vue +1 -1
  11. package/src/components/page-section-tokens.js +613 -0
  12. package/src/composables/useReadingProgress.js +46 -0
  13. package/src/pages/guide/getting-started.overview.en-US.md +2 -2
  14. package/src/pages/guide/getting-started.overview.pt-BR.md +2 -2
  15. package/src/pages/guide/i18n-and-markdown.overview.en-US.md +16 -0
  16. package/src/pages/guide/i18n-and-markdown.overview.pt-BR.md +16 -0
  17. package/src/pages/guide.index.js +48 -0
  18. package/src/pages/manual/components/d-menu.overview.en-US.md +1 -1
  19. package/src/pages/manual/components/d-menu.overview.pt-BR.md +1 -1
  20. package/src/pages/manual/components/d-page-expandable.overview.en-US.md +58 -0
  21. package/src/pages/manual/components/d-page-expandable.overview.pt-BR.md +58 -0
  22. package/src/pages/manual/components/d-page-expandable.showcase.en-US.md +33 -0
  23. package/src/pages/manual/components/d-page-expandable.showcase.pt-BR.md +33 -0
  24. package/src/pages/manual/components/d-page.overview.en-US.md +3 -0
  25. package/src/pages/manual/components/d-page.overview.pt-BR.md +3 -0
  26. package/src/pages/manual/components/d-subpage.overview.en-US.md +5 -1
  27. package/src/pages/manual/components/d-subpage.overview.pt-BR.md +5 -1
  28. package/src/pages/manual.index.js +102 -0
  29. package/src/quasar.factory.js +158 -13
  30. package/src/search/book-search.js +25 -0
  31. package/public/Docsphere/flags/brazil.png +0 -0
  32. package/public/Docsphere/flags/united-states-of-america.png +0 -0
  33. package/src/i18n/tags.hjson +0 -46
  34. /package/public/{Docsphere → images}/flags/abkhazia.png +0 -0
  35. /package/public/{Docsphere → images}/flags/afghanistan.png +0 -0
  36. /package/public/{Docsphere → images}/flags/aland-islands.png +0 -0
  37. /package/public/{Docsphere → images}/flags/albania.png +0 -0
  38. /package/public/{Docsphere → images}/flags/algeria.png +0 -0
  39. /package/public/{Docsphere → images}/flags/american-samoa.png +0 -0
  40. /package/public/{Docsphere → images}/flags/andorra.png +0 -0
  41. /package/public/{Docsphere → images}/flags/angola.png +0 -0
  42. /package/public/{Docsphere → images}/flags/anguilla.png +0 -0
  43. /package/public/{Docsphere → images}/flags/antigua-and-barbuda.png +0 -0
  44. /package/public/{Docsphere → images}/flags/argentina.png +0 -0
  45. /package/public/{Docsphere → images}/flags/armenia.png +0 -0
  46. /package/public/{Docsphere → images}/flags/aruba.png +0 -0
  47. /package/public/{Docsphere → images}/flags/australia.png +0 -0
  48. /package/public/{Docsphere → images}/flags/austria.png +0 -0
  49. /package/public/{Docsphere → images}/flags/azerbaijan.png +0 -0
  50. /package/public/{Docsphere → images}/flags/azores-islands.png +0 -0
  51. /package/public/{Docsphere → images}/flags/bahamas.png +0 -0
  52. /package/public/{Docsphere → images}/flags/bahrain.png +0 -0
  53. /package/public/{Docsphere → images}/flags/balearic-islands.png +0 -0
  54. /package/public/{Docsphere → images}/flags/bangladesh.png +0 -0
  55. /package/public/{Docsphere → images}/flags/barbados.png +0 -0
  56. /package/public/{Docsphere → images}/flags/basque-country.png +0 -0
  57. /package/public/{Docsphere → images}/flags/belarus.png +0 -0
  58. /package/public/{Docsphere → images}/flags/belgium.png +0 -0
  59. /package/public/{Docsphere → images}/flags/belize.png +0 -0
  60. /package/public/{Docsphere → images}/flags/benin.png +0 -0
  61. /package/public/{Docsphere → images}/flags/bermuda.png +0 -0
  62. /package/public/{Docsphere → images}/flags/bhutan-1.png +0 -0
  63. /package/public/{Docsphere → images}/flags/bhutan.png +0 -0
  64. /package/public/{Docsphere → images}/flags/bolivia.png +0 -0
  65. /package/public/{Docsphere → images}/flags/bonaire.png +0 -0
  66. /package/public/{Docsphere → images}/flags/bosnia-and-herzegovina.png +0 -0
  67. /package/public/{Docsphere → images}/flags/botswana.png +0 -0
  68. /package/public/{Docsphere → images}/flags/british-columbia.png +0 -0
  69. /package/public/{Docsphere → images}/flags/british-indian-ocean-territory.png +0 -0
  70. /package/public/{Docsphere → images}/flags/british-virgin-islands.png +0 -0
  71. /package/public/{Docsphere → images}/flags/brunei.png +0 -0
  72. /package/public/{Docsphere → images}/flags/bulgaria.png +0 -0
  73. /package/public/{Docsphere → images}/flags/burkina-faso.png +0 -0
  74. /package/public/{Docsphere → images}/flags/burundi.png +0 -0
  75. /package/public/{Docsphere → images}/flags/cambodia.png +0 -0
  76. /package/public/{Docsphere → images}/flags/cameroon.png +0 -0
  77. /package/public/{Docsphere → images}/flags/canada.png +0 -0
  78. /package/public/{Docsphere → images}/flags/canary-islands.png +0 -0
  79. /package/public/{Docsphere → images}/flags/cape-verde.png +0 -0
  80. /package/public/{Docsphere → images}/flags/cayman-islands.png +0 -0
  81. /package/public/{Docsphere → images}/flags/central-african-republic.png +0 -0
  82. /package/public/{Docsphere → images}/flags/ceuta.png +0 -0
  83. /package/public/{Docsphere → images}/flags/chad.png +0 -0
  84. /package/public/{Docsphere → images}/flags/chile.png +0 -0
  85. /package/public/{Docsphere → images}/flags/china.png +0 -0
  86. /package/public/{Docsphere → images}/flags/christmas-island.png +0 -0
  87. /package/public/{Docsphere → images}/flags/cocos-island.png +0 -0
  88. /package/public/{Docsphere → images}/flags/colombia.png +0 -0
  89. /package/public/{Docsphere → images}/flags/comoros.png +0 -0
  90. /package/public/{Docsphere → images}/flags/cook-islands.png +0 -0
  91. /package/public/{Docsphere → images}/flags/corsica.png +0 -0
  92. /package/public/{Docsphere → images}/flags/costa-rica.png +0 -0
  93. /package/public/{Docsphere → images}/flags/croatia.png +0 -0
  94. /package/public/{Docsphere → images}/flags/cuba.png +0 -0
  95. /package/public/{Docsphere → images}/flags/curacao.png +0 -0
  96. /package/public/{Docsphere → images}/flags/cyprus.png +0 -0
  97. /package/public/{Docsphere → images}/flags/czech-republic.png +0 -0
  98. /package/public/{Docsphere → images}/flags/democratic-republic-of-congo.png +0 -0
  99. /package/public/{Docsphere → images}/flags/denmark.png +0 -0
  100. /package/public/{Docsphere → images}/flags/djibouti.png +0 -0
  101. /package/public/{Docsphere → images}/flags/dominica.png +0 -0
  102. /package/public/{Docsphere → images}/flags/dominican-republic.png +0 -0
  103. /package/public/{Docsphere → images}/flags/east-timor.png +0 -0
  104. /package/public/{Docsphere → images}/flags/ecuador.png +0 -0
  105. /package/public/{Docsphere → images}/flags/egypt.png +0 -0
  106. /package/public/{Docsphere → images}/flags/england.png +0 -0
  107. /package/public/{Docsphere → images}/flags/equatorial-guinea.png +0 -0
  108. /package/public/{Docsphere → images}/flags/eritrea.png +0 -0
  109. /package/public/{Docsphere → images}/flags/estonia.png +0 -0
  110. /package/public/{Docsphere → images}/flags/ethiopia.png +0 -0
  111. /package/public/{Docsphere → images}/flags/european-union.png +0 -0
  112. /package/public/{Docsphere → images}/flags/falkland-islands.png +0 -0
  113. /package/public/{Docsphere → images}/flags/faroe-islands.png +0 -0
  114. /package/public/{Docsphere → images}/flags/fiji.png +0 -0
  115. /package/public/{Docsphere → images}/flags/finland.png +0 -0
  116. /package/public/{Docsphere → images}/flags/france.png +0 -0
  117. /package/public/{Docsphere → images}/flags/french-polynesia.png +0 -0
  118. /package/public/{Docsphere → images}/flags/gabon.png +0 -0
  119. /package/public/{Docsphere → images}/flags/galapagos-islands.png +0 -0
  120. /package/public/{Docsphere → images}/flags/gambia.png +0 -0
  121. /package/public/{Docsphere → images}/flags/georgia.png +0 -0
  122. /package/public/{Docsphere → images}/flags/germany.png +0 -0
  123. /package/public/{Docsphere → images}/flags/ghana.png +0 -0
  124. /package/public/{Docsphere → images}/flags/gibraltar.png +0 -0
  125. /package/public/{Docsphere → images}/flags/greece.png +0 -0
  126. /package/public/{Docsphere → images}/flags/greenland.png +0 -0
  127. /package/public/{Docsphere → images}/flags/grenada.png +0 -0
  128. /package/public/{Docsphere → images}/flags/guam.png +0 -0
  129. /package/public/{Docsphere → images}/flags/guatemala.png +0 -0
  130. /package/public/{Docsphere → images}/flags/guernsey.png +0 -0
  131. /package/public/{Docsphere → images}/flags/guinea-bissau.png +0 -0
  132. /package/public/{Docsphere → images}/flags/guinea.png +0 -0
  133. /package/public/{Docsphere → images}/flags/guyana.png +0 -0
  134. /package/public/{Docsphere → images}/flags/haiti.png +0 -0
  135. /package/public/{Docsphere → images}/flags/hawaii.png +0 -0
  136. /package/public/{Docsphere → images}/flags/honduras.png +0 -0
  137. /package/public/{Docsphere → images}/flags/hong-kong.png +0 -0
  138. /package/public/{Docsphere → images}/flags/hungary.png +0 -0
  139. /package/public/{Docsphere → images}/flags/iceland.png +0 -0
  140. /package/public/{Docsphere → images}/flags/india.png +0 -0
  141. /package/public/{Docsphere → images}/flags/indonesia.png +0 -0
  142. /package/public/{Docsphere → images}/flags/iran.png +0 -0
  143. /package/public/{Docsphere → images}/flags/iraq.png +0 -0
  144. /package/public/{Docsphere → images}/flags/ireland.png +0 -0
  145. /package/public/{Docsphere → images}/flags/isle-of-man.png +0 -0
  146. /package/public/{Docsphere → images}/flags/israel.png +0 -0
  147. /package/public/{Docsphere → images}/flags/italy.png +0 -0
  148. /package/public/{Docsphere → images}/flags/ivory-coast.png +0 -0
  149. /package/public/{Docsphere → images}/flags/jamaica.png +0 -0
  150. /package/public/{Docsphere → images}/flags/japan.png +0 -0
  151. /package/public/{Docsphere → images}/flags/jersey.png +0 -0
  152. /package/public/{Docsphere → images}/flags/jordan.png +0 -0
  153. /package/public/{Docsphere → images}/flags/kazakhstan.png +0 -0
  154. /package/public/{Docsphere → images}/flags/kenya.png +0 -0
  155. /package/public/{Docsphere → images}/flags/kiribati.png +0 -0
  156. /package/public/{Docsphere → images}/flags/kosovo.png +0 -0
  157. /package/public/{Docsphere → images}/flags/kuwait.png +0 -0
  158. /package/public/{Docsphere → images}/flags/kyrgyzstan.png +0 -0
  159. /package/public/{Docsphere → images}/flags/laos.png +0 -0
  160. /package/public/{Docsphere → images}/flags/latvia.png +0 -0
  161. /package/public/{Docsphere → images}/flags/lebanon.png +0 -0
  162. /package/public/{Docsphere → images}/flags/lesotho.png +0 -0
  163. /package/public/{Docsphere → images}/flags/liberia.png +0 -0
  164. /package/public/{Docsphere → images}/flags/libya.png +0 -0
  165. /package/public/{Docsphere → images}/flags/liechtenstein.png +0 -0
  166. /package/public/{Docsphere → images}/flags/lithuania.png +0 -0
  167. /package/public/{Docsphere → images}/flags/luxembourg.png +0 -0
  168. /package/public/{Docsphere → images}/flags/macao.png +0 -0
  169. /package/public/{Docsphere → images}/flags/madagascar.png +0 -0
  170. /package/public/{Docsphere → images}/flags/madeira.png +0 -0
  171. /package/public/{Docsphere → images}/flags/malawi.png +0 -0
  172. /package/public/{Docsphere → images}/flags/malaysia.png +0 -0
  173. /package/public/{Docsphere → images}/flags/maldives.png +0 -0
  174. /package/public/{Docsphere → images}/flags/mali.png +0 -0
  175. /package/public/{Docsphere → images}/flags/malta.png +0 -0
  176. /package/public/{Docsphere → images}/flags/marshall-island.png +0 -0
  177. /package/public/{Docsphere → images}/flags/martinique.png +0 -0
  178. /package/public/{Docsphere → images}/flags/mauritania.png +0 -0
  179. /package/public/{Docsphere → images}/flags/mauritius.png +0 -0
  180. /package/public/{Docsphere → images}/flags/melilla.png +0 -0
  181. /package/public/{Docsphere → images}/flags/mexico.png +0 -0
  182. /package/public/{Docsphere → images}/flags/micronesia.png +0 -0
  183. /package/public/{Docsphere → images}/flags/moldova.png +0 -0
  184. /package/public/{Docsphere → images}/flags/monaco.png +0 -0
  185. /package/public/{Docsphere → images}/flags/mongolia.png +0 -0
  186. /package/public/{Docsphere → images}/flags/montenegro.png +0 -0
  187. /package/public/{Docsphere → images}/flags/montserrat.png +0 -0
  188. /package/public/{Docsphere → images}/flags/morocco.png +0 -0
  189. /package/public/{Docsphere → images}/flags/mozambique.png +0 -0
  190. /package/public/{Docsphere → images}/flags/myanmar.png +0 -0
  191. /package/public/{Docsphere → images}/flags/namibia.png +0 -0
  192. /package/public/{Docsphere → images}/flags/nato.png +0 -0
  193. /package/public/{Docsphere → images}/flags/nauru.png +0 -0
  194. /package/public/{Docsphere → images}/flags/nepal.png +0 -0
  195. /package/public/{Docsphere → images}/flags/netherlands.png +0 -0
  196. /package/public/{Docsphere → images}/flags/new-zealand.png +0 -0
  197. /package/public/{Docsphere → images}/flags/nicaragua.png +0 -0
  198. /package/public/{Docsphere → images}/flags/niger.png +0 -0
  199. /package/public/{Docsphere → images}/flags/nigeria.png +0 -0
  200. /package/public/{Docsphere → images}/flags/niue.png +0 -0
  201. /package/public/{Docsphere → images}/flags/norfolk-island.png +0 -0
  202. /package/public/{Docsphere → images}/flags/north-korea.png +0 -0
  203. /package/public/{Docsphere → images}/flags/northen-cyprus.png +0 -0
  204. /package/public/{Docsphere → images}/flags/northern-marianas-islands.png +0 -0
  205. /package/public/{Docsphere → images}/flags/norway.png +0 -0
  206. /package/public/{Docsphere → images}/flags/oman.png +0 -0
  207. /package/public/{Docsphere → images}/flags/orkney-islands.png +0 -0
  208. /package/public/{Docsphere → images}/flags/ossetia.png +0 -0
  209. /package/public/{Docsphere → images}/flags/pakistan.png +0 -0
  210. /package/public/{Docsphere → images}/flags/palau.png +0 -0
  211. /package/public/{Docsphere → images}/flags/palestine.png +0 -0
  212. /package/public/{Docsphere → images}/flags/panama.png +0 -0
  213. /package/public/{Docsphere → images}/flags/papua-new-guinea.png +0 -0
  214. /package/public/{Docsphere → images}/flags/paraguay.png +0 -0
  215. /package/public/{Docsphere → images}/flags/peru.png +0 -0
  216. /package/public/{Docsphere → images}/flags/philippines.png +0 -0
  217. /package/public/{Docsphere → images}/flags/pitcairn-islands.png +0 -0
  218. /package/public/{Docsphere → images}/flags/portugal.png +0 -0
  219. /package/public/{Docsphere → images}/flags/puerto-rico.png +0 -0
  220. /package/public/{Docsphere → images}/flags/qatar.png +0 -0
  221. /package/public/{Docsphere → images}/flags/rapa-nui.png +0 -0
  222. /package/public/{Docsphere → images}/flags/republic-of-macedonia.png +0 -0
  223. /package/public/{Docsphere → images}/flags/republic-of-poland.png +0 -0
  224. /package/public/{Docsphere → images}/flags/republic-of-the-congo.png +0 -0
  225. /package/public/{Docsphere → images}/flags/romania.png +0 -0
  226. /package/public/{Docsphere → images}/flags/russia.png +0 -0
  227. /package/public/{Docsphere → images}/flags/rwanda.png +0 -0
  228. /package/public/{Docsphere → images}/flags/saba-island.png +0 -0
  229. /package/public/{Docsphere → images}/flags/saint-kitts-and-nevis.png +0 -0
  230. /package/public/{Docsphere → images}/flags/salvador.png +0 -0
  231. /package/public/{Docsphere → images}/flags/samoa.png +0 -0
  232. /package/public/{Docsphere → images}/flags/san-marino.png +0 -0
  233. /package/public/{Docsphere → images}/flags/sao-tome-and-principe.png +0 -0
  234. /package/public/{Docsphere → images}/flags/sardinia.png +0 -0
  235. /package/public/{Docsphere → images}/flags/saudi-arabia.png +0 -0
  236. /package/public/{Docsphere → images}/flags/scotland.png +0 -0
  237. /package/public/{Docsphere → images}/flags/senegal.png +0 -0
  238. /package/public/{Docsphere → images}/flags/serbia.png +0 -0
  239. /package/public/{Docsphere → images}/flags/seychelles.png +0 -0
  240. /package/public/{Docsphere → images}/flags/sierra-leone.png +0 -0
  241. /package/public/{Docsphere → images}/flags/singapore.png +0 -0
  242. /package/public/{Docsphere → images}/flags/sint-eustatius.png +0 -0
  243. /package/public/{Docsphere → images}/flags/sint-maarten.png +0 -0
  244. /package/public/{Docsphere → images}/flags/slovakia.png +0 -0
  245. /package/public/{Docsphere → images}/flags/slovenia.png +0 -0
  246. /package/public/{Docsphere → images}/flags/solomon-islands.png +0 -0
  247. /package/public/{Docsphere → images}/flags/somalia.png +0 -0
  248. /package/public/{Docsphere → images}/flags/somaliland.png +0 -0
  249. /package/public/{Docsphere → images}/flags/south-africa.png +0 -0
  250. /package/public/{Docsphere → images}/flags/south-korea.png +0 -0
  251. /package/public/{Docsphere → images}/flags/south-sudan.png +0 -0
  252. /package/public/{Docsphere → images}/flags/spain.png +0 -0
  253. /package/public/{Docsphere → images}/flags/sri-lanka.png +0 -0
  254. /package/public/{Docsphere → images}/flags/st-barts.png +0 -0
  255. /package/public/{Docsphere → images}/flags/st-lucia.png +0 -0
  256. /package/public/{Docsphere → images}/flags/st-vincent-and-the-grenadines.png +0 -0
  257. /package/public/{Docsphere → images}/flags/sudan.png +0 -0
  258. /package/public/{Docsphere → images}/flags/suriname.png +0 -0
  259. /package/public/{Docsphere → images}/flags/swaziland.png +0 -0
  260. /package/public/{Docsphere → images}/flags/sweden.png +0 -0
  261. /package/public/{Docsphere → images}/flags/switzerland.png +0 -0
  262. /package/public/{Docsphere → images}/flags/syria.png +0 -0
  263. /package/public/{Docsphere → images}/flags/taiwan.png +0 -0
  264. /package/public/{Docsphere → images}/flags/tajikistan.png +0 -0
  265. /package/public/{Docsphere → images}/flags/tanzania.png +0 -0
  266. /package/public/{Docsphere → images}/flags/thailand.png +0 -0
  267. /package/public/{Docsphere → images}/flags/tibet.png +0 -0
  268. /package/public/{Docsphere → images}/flags/togo.png +0 -0
  269. /package/public/{Docsphere → images}/flags/tokelau.png +0 -0
  270. /package/public/{Docsphere → images}/flags/tonga.png +0 -0
  271. /package/public/{Docsphere → images}/flags/transnistria.png +0 -0
  272. /package/public/{Docsphere → images}/flags/trinidad-and-tobago.png +0 -0
  273. /package/public/{Docsphere → images}/flags/tunisia.png +0 -0
  274. /package/public/{Docsphere → images}/flags/turkey.png +0 -0
  275. /package/public/{Docsphere → images}/flags/turkmenistan.png +0 -0
  276. /package/public/{Docsphere → images}/flags/turks-and-caicos.png +0 -0
  277. /package/public/{Docsphere → images}/flags/tuvalu.png +0 -0
  278. /package/public/{Docsphere → images}/flags/uganda.png +0 -0
  279. /package/public/{Docsphere → images}/flags/ukraine.png +0 -0
  280. /package/public/{Docsphere → images}/flags/united-arab-emirates.png +0 -0
  281. /package/public/{Docsphere → images}/flags/united-kingdom.png +0 -0
  282. /package/public/{Docsphere → images}/flags/united-nations.png +0 -0
  283. /package/public/{Docsphere → images}/flags/uruguay.png +0 -0
  284. /package/public/{Docsphere → images}/flags/uzbekistn.png +0 -0
  285. /package/public/{Docsphere → images}/flags/vanuatu.png +0 -0
  286. /package/public/{Docsphere → images}/flags/vatican-city.png +0 -0
  287. /package/public/{Docsphere → images}/flags/venezuela.png +0 -0
  288. /package/public/{Docsphere → images}/flags/vietnam.png +0 -0
  289. /package/public/{Docsphere → images}/flags/virgin-islands.png +0 -0
  290. /package/public/{Docsphere → images}/flags/wales.png +0 -0
  291. /package/public/{Docsphere → images}/flags/western-sahara.png +0 -0
  292. /package/public/{Docsphere → images}/flags/yemen.png +0 -0
  293. /package/public/{Docsphere → images}/flags/zambia.png +0 -0
  294. /package/public/{Docsphere → images}/flags/zimbabwe.png +0 -0
package/README.md CHANGED
@@ -54,6 +54,7 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
54
54
  - 📚 **Book Tabs with Per-State Colors** — Define `*.book.js` tabs with icons, order, and `color.active` / `color.inactive`
55
55
  - 🔀 **Internal Shortcut Pages** — Route entries can redirect with `config.link.to`, keeping localized titles while inheriting icon/status from the destination page
56
56
  - 📐 **Responsive Subpage Toolbar** — Subpage actions align with the content column on desktop and dock to the bottom on mobile
57
+ - ⬆️ **Reading Progress Back to Top** — Documentation subpages can show a floating back-to-top control with circular reading progress that stays above the mobile subpage toolbar
57
58
  - 🏷️ **Status Badges** — Mark pages as `done`, `draft`, `empty`, or `new` with visual indicators
58
59
  - ✏️ **Edit on GitHub** — Direct links to edit pages on your repository
59
60
  - 🧭 **Robust Edit Link Mapping** — Normalizes route paths (including trailing slashes) into `page.subpage.locale.md` source files for reliable GitHub edit URLs
@@ -66,6 +67,7 @@ Transform Markdown content into beautiful, navigable documentation sites — wit
66
67
  - 🏠 **Markdown Home at Root** — Homepage is rendered from `src/pages/Homepage.{lang}.md` directly at `/`
67
68
  - 🌍 **Remote README as Home** — Optional build-time remote README source for homepage with automatic local fallback
68
69
  - 🧬 **Scaffolded Homepage Override Wiring** — New consumer projects automatically wire `virtual:docsector-homepage-override` into i18n message building
70
+ - 📖 **Expandable Markdown Sections** — Use `<d-expandable title="...">...</d-expandable>` to collapse secondary content while keeping rich Markdown support inside the body
69
71
  - 🧭 **Quick Links Custom Element** — Use `<d-quick-links>` and `<d-quick-link>` in Markdown to render rich home navigation cards
70
72
  - 🗂️ **API Catalog Well-Known** — Auto-generates `/.well-known/api-catalog` as Linkset JSON for machine-readable API discovery
71
73
  - 🗃️ **Multi-Version History** — Archive older major versions under `src/pages/.old/<version>/` and expose them at prefixed routes (e.g. `/v0.x/guide/...`) while keeping the current docs at unprefixed routes
@@ -668,7 +670,6 @@ export default configure(() => {
668
670
  | `pages` | project `src/pages/` | consumer `src/pages/` |
669
671
  | `src/i18n` | project `src/i18n/` | consumer `src/i18n/` |
670
672
  | `docsector.config.js` | project root | consumer root |
671
- | `@docsector/tags` | project `src/i18n/tags.hjson` | consumer `src/i18n/tags.hjson` |
672
673
 
673
674
  ---
674
675
 
@@ -810,17 +811,29 @@ src/i18n/languages/en-US.hjson
810
811
  src/i18n/languages/pt-BR.hjson
811
812
  ```
812
813
 
813
- ### Search tags (`src/i18n/tags.hjson`)
814
+ ### Search tags (`src/pages/*.index.js`)
814
815
 
815
- Provide search keywords per route and locale for menu search:
816
+ Define search keywords per page using `metadata.tags` in each book registry file:
816
817
 
817
- ```hjson
818
- {
819
- "en-US": {
820
- "/manual/my-section/my-page": "keyword1 keyword2 keyword3"
821
- }
822
- "pt-BR": {
823
- "/manual/my-section/my-page": "palavra1 palavra2 palavra3"
818
+ ```javascript
819
+ export default {
820
+ '/my-section/my-page': {
821
+ config: {
822
+ icon: 'description',
823
+ book: 'manual',
824
+ status: 'done',
825
+ subpages: { showcase: false }
826
+ },
827
+ data: {
828
+ 'en-US': { title: 'My Page' },
829
+ 'pt-BR': { title: 'Minha Página' }
830
+ },
831
+ metadata: {
832
+ tags: {
833
+ 'en-US': 'keyword1 keyword2 keyword3',
834
+ 'pt-BR': 'palavra1 palavra2 palavra3'
835
+ }
836
+ }
824
837
  }
825
838
  }
826
839
  ```
@@ -845,28 +858,19 @@ my-docs/
845
858
  │ │ └── manual/ # Manual pages (.md files)
846
859
  │ ├── i18n/
847
860
  │ │ ├── index.js # Uses buildMessages() from engine
848
- │ │ ├── tags.hjson # Search keywords per route/locale
849
861
  │ │ └── languages/ # HJSON locale files
850
862
  │ ├── css/
851
863
  │ │ └── app.sass # Optional overrides (imports engine CSS)
852
864
  │ └── boot/ # Consumer-specific boot files
853
865
  │ └── qmediaplayer.js # Example: custom Quasar extension
854
866
  └── public/
855
- ├── images/logo/ # Project logo
856
- ├── images/flags/ # Locale flag images
867
+ ├── images/logo.png # Project logo
868
+ ├── flags/ # Locale flag images
857
869
  └── icons/ # PWA icons
858
870
  ```
859
871
 
860
872
  ---
861
873
 
862
- ## ⚠️ Migrating from 1.x to 2.0
863
-
864
- - Split the legacy `src/pages/index.js` registry into per-book files such as `src/pages/manual.book.js`, `src/pages/manual.index.js`, `src/pages/guide.book.js`, and `src/pages/guide.index.js`.
865
- - Update i18n wiring to import `books` from `virtual:docsector-books` and pass it to `buildMessages({ ... })`.
866
- - Rename `config.type` to `config.book` in page definitions. Legacy fallback still works, but `config.book` is the supported API moving forward.
867
-
868
- ---
869
-
870
874
  ## 📚 Defining Books (Tabs)
871
875
 
872
876
  Each documentation tab is defined by a `*.book.js` file paired with a matching `*.index.js` registry.
@@ -886,6 +890,31 @@ export default defineBook({
886
890
  })
887
891
  ```
888
892
 
893
+ Declare menu search tags in each page entry under `metadata.tags`:
894
+
895
+ ```javascript
896
+ export default {
897
+ '/getting-started': {
898
+ config: {
899
+ icon: 'flag',
900
+ book: 'guide',
901
+ status: 'done',
902
+ subpages: { showcase: false }
903
+ },
904
+ data: {
905
+ 'en-US': { title: 'Getting Started' },
906
+ 'pt-BR': { title: 'Começando' }
907
+ },
908
+ metadata: {
909
+ tags: {
910
+ 'en-US': 'install setup start begin quick project structure',
911
+ 'pt-BR': 'instalar configurar iniciar começar rápido projeto estrutura'
912
+ }
913
+ }
914
+ }
915
+ }
916
+ ```
917
+
889
918
  Notes:
890
919
 
891
920
  - `color.active` and `color.inactive` control the tab text color for each state.
package/bin/docsector.js CHANGED
@@ -23,7 +23,7 @@ const packageRoot = resolve(__dirname, '..')
23
23
  const args = process.argv.slice(2)
24
24
  const command = args[0]
25
25
 
26
- const VERSION = '2.3.0'
26
+ const VERSION = '3.1.0'
27
27
 
28
28
  const HELP = `
29
29
  Docsector Reader v${VERSION}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docsector/docsector-reader",
3
- "version": "2.3.0",
3
+ "version": "3.1.0",
4
4
  "description": "A documentation rendering engine built with Vue 3, Quasar v2 and Vite. Transform Markdown into beautiful, navigable documentation sites.",
5
5
  "productName": "Docsector Reader",
6
6
  "author": "Rodrigo de Araujo Vieira",
@@ -60,7 +60,8 @@
60
60
  "build": "quasar build",
61
61
  "lint": "eslint --ext .js,.vue ./",
62
62
  "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
63
- "test": "echo \"No test specified\" && exit 0"
63
+ "test": "vitest run",
64
+ "test:watch": "vitest"
64
65
  },
65
66
  "dependencies": {
66
67
  "@quasar/app-vite": "^2.1.0",
@@ -96,7 +97,8 @@
96
97
  "eslint-plugin-n": "^15.0.0",
97
98
  "eslint-plugin-promise": "^6.0.0",
98
99
  "eslint-plugin-vue": "^9.0.0",
99
- "prettier": "^2.5.1"
100
+ "prettier": "^2.5.1",
101
+ "vitest": "^2.1.8"
100
102
  },
101
103
  "browserslist": [
102
104
  "last 10 Chrome versions",
@@ -4,11 +4,11 @@ import { useRoute, useRouter } from 'vue-router'
4
4
  import { useQuasar, scroll, openURL } from 'quasar'
5
5
  import { useI18n } from 'vue-i18n'
6
6
 
7
- import tags from '@docsector/tags'
8
7
  import DMenuItem from './DMenuItem.vue'
9
8
  import docsectorConfig from 'docsector.config.js'
10
- import { allBooks, booksByVersion, versions } from 'virtual:docsector-books'
9
+ import { allBooks, booksByVersion, bookTagsByVersion, versions } from 'virtual:docsector-books'
11
10
  import { namespacedLabelI18nPath, routeSubpageSourceI18nPath } from '../i18n/path'
11
+ import { matchesBookSearchTerm } from '../search/book-search'
12
12
 
13
13
  const $q = useQuasar()
14
14
  const $route = useRoute()
@@ -42,6 +42,14 @@ const activeBooks = computed(() => {
42
42
  return allBooks || []
43
43
  })
44
44
 
45
+ const activeBookTags = computed(() => {
46
+ if (activeVersionId.value && bookTagsByVersion?.[activeVersionId.value]) {
47
+ return bookTagsByVersion[activeVersionId.value]
48
+ }
49
+
50
+ return {}
51
+ })
52
+
45
53
  const draftReleaseStatuses = new Set(['draft', 'unreleased', 'preview', 'next'])
46
54
 
47
55
  const versionStatusLabel = (label, releaseStatus) => {
@@ -249,15 +257,14 @@ const searchTermIterate = (items, term, locale) => {
249
257
  } else if (typeof items === 'object') {
250
258
  const item = items
251
259
  const path = item.path
260
+ const routeBook = item.meta?.book ?? item.meta?.type ?? null
252
261
  const tagPath = item.meta?.unversionedPath || path
253
262
  founds.value[path] = false
254
263
 
255
- // @ search in i18n/tags.hjson
256
- if (tags[locale] && Object.keys(tags[locale]).length > 0) {
257
- founds.value[path] = tags[locale][tagPath]?.indexOf(term) !== -1
258
- if (founds.value[path] === false && locale !== 'en-US') {
259
- founds.value[path] = tags['en-US'][tagPath]?.indexOf(term) !== -1
260
- }
264
+ // @ search in tags declared by active book index
265
+ if (routeBook) {
266
+ const tagsByLocale = activeBookTags.value?.[routeBook] || {}
267
+ founds.value[path] = matchesBookSearchTerm(tagsByLocale, locale, tagPath, term)
261
268
  }
262
269
 
263
270
  // @ search in Page content
@@ -5,6 +5,7 @@ import { useRoute, useRouter } from 'vue-router'
5
5
  import { useQuasar } from 'quasar'
6
6
 
7
7
  import useNavigator from '../composables/useNavigator'
8
+ import { getReadingProgressState } from '../composables/useReadingProgress'
8
9
 
9
10
  import DPageAnchor from './DPageAnchor.vue'
10
11
  import DPageMeta from './DPageMeta.vue'
@@ -20,6 +21,10 @@ const props = defineProps({
20
21
  disableNav: {
21
22
  type: Boolean,
22
23
  default: false
24
+ },
25
+ showBackToTopControl: {
26
+ type: Boolean,
27
+ default: false
23
28
  }
24
29
  })
25
30
 
@@ -29,6 +34,26 @@ const submenu = ref(null)
29
34
  const pageMinHeight = ref('calc(100vh - 86px)')
30
35
  const submenuHeight = ref('36px')
31
36
  const pageBottomInset = ref('0px')
37
+ const readingProgress = ref(getReadingProgressState())
38
+
39
+ const getPageScrollContainer = () => {
40
+ return pageScrollArea.value?.$el?.querySelector('.q-scrollarea__container') || null
41
+ }
42
+
43
+ const syncReadingProgress = (scrollTop = null) => {
44
+ const container = getPageScrollContainer()
45
+
46
+ if (!container) {
47
+ readingProgress.value = getReadingProgressState()
48
+ return
49
+ }
50
+
51
+ readingProgress.value = getReadingProgressState({
52
+ scrollTop: scrollTop ?? container.scrollTop,
53
+ scrollHeight: container.scrollHeight,
54
+ clientHeight: container.clientHeight
55
+ })
56
+ }
32
57
 
33
58
  const updatePageMinHeight = () => {
34
59
  const pageContainerEl = pageContainer.value?.$el || pageContainer.value
@@ -47,6 +72,7 @@ const updatePageMinHeight = () => {
47
72
  pageMinHeight.value = `calc(100vh - ${totalOffset}px)`
48
73
  submenuHeight.value = `${Math.max(36, Math.round(measuredSubmenuHeight))}px`
49
74
  pageBottomInset.value = isMobile ? submenuHeight.value : '0px'
75
+ syncReadingProgress()
50
76
  }
51
77
 
52
78
  const schedulePageMinHeightUpdate = () => {
@@ -80,6 +106,12 @@ const main = computed(() => {
80
106
  return 'overview'
81
107
  }
82
108
  })
109
+ const shouldShowBackToTopControl = computed(() => {
110
+ return props.showBackToTopControl && readingProgress.value.hasOverflow && readingProgress.value.isVisible
111
+ })
112
+ const backToTopRightOffset = computed(() => {
113
+ return layoutMeta.value && !$q.screen.lt.md ? '332px' : '24px'
114
+ })
83
115
 
84
116
  const toggleSectionsTree = () => {
85
117
  layoutMeta.value = !layoutMeta.value
@@ -133,10 +165,7 @@ const resetPageScroll = () => {
133
165
  if (pageScrollArea.value !== null) {
134
166
  pageScrollArea.value.setScrollPosition('vertical', 0, 0)
135
167
  }
136
- }
137
-
138
- const getPageScrollContainer = () => {
139
- return pageScrollArea.value?.$el?.querySelector('.q-scrollarea__container') || null
168
+ syncReadingProgress(0)
140
169
  }
141
170
 
142
171
  const isEditableTarget = (target) => {
@@ -208,6 +237,15 @@ const handleMainScrollKeys = (event) => {
208
237
  container.scrollTop = nextTop
209
238
  }
210
239
 
240
+ const handlePageScroll = (scrollState) => {
241
+ scrolling(scrollState)
242
+ syncReadingProgress(scrollState?.position?.top)
243
+ }
244
+
245
+ const scrollToTop = () => {
246
+ navigate(0)
247
+ }
248
+
211
249
  onMounted(() => {
212
250
  window.addEventListener('keydown', handleMainScrollKeys)
213
251
  window.addEventListener('resize', schedulePageMinHeightUpdate)
@@ -236,6 +274,7 @@ onBeforeUnmount(() => {
236
274
  watch(() => route.fullPath, () => {
237
275
  nextTick(() => {
238
276
  schedulePageMinHeightUpdate()
277
+ syncReadingProgress(0)
239
278
  })
240
279
  })
241
280
  </script>
@@ -292,10 +331,38 @@ watch(() => route.fullPath, () => {
292
331
  <slot />
293
332
  </div>
294
333
  <d-page-meta v-if="!disableNav" />
295
- <q-scroll-observer @scroll="scrolling" :debounce="300" />
334
+ <q-scroll-observer @scroll="handlePageScroll" :debounce="300" />
296
335
  </q-scroll-area>
297
336
  </q-page>
298
337
 
338
+ <div
339
+ v-if="shouldShowBackToTopControl"
340
+ class="d-back-to-top"
341
+ :style="{ '--d-back-to-top-right': backToTopRightOffset }"
342
+ >
343
+ <q-circular-progress
344
+ class="d-back-to-top__progress"
345
+ :value="readingProgress.progressPercent"
346
+ size="58px"
347
+ :thickness="0.16"
348
+ color="primary"
349
+ track-color="grey-5"
350
+ />
351
+ <q-btn
352
+ class="d-back-to-top__button"
353
+ round
354
+ dense
355
+ unelevated
356
+ color="dark"
357
+ text-color="white"
358
+ icon="north"
359
+ :aria-label="$t('system.backToTop')"
360
+ @click="scrollToTop"
361
+ >
362
+ <q-tooltip anchor="top middle" self="bottom middle" :offset="[10, 10]">{{ $t('system.backToTop') }}</q-tooltip>
363
+ </q-btn>
364
+ </div>
365
+
299
366
  <q-drawer elevated show-if-above side="right" v-model="layoutMeta">
300
367
  <d-page-anchor id="anchor" />
301
368
  </q-drawer>
@@ -321,6 +388,25 @@ watch(() => route.fullPath, () => {
321
388
  #page
322
389
  min-height: var(--d-page-min-height, calc(100vh - 86px)) !important
323
390
 
391
+ .d-back-to-top
392
+ position: fixed
393
+ right: var(--d-back-to-top-right, 24px)
394
+ bottom: calc(24px + var(--d-page-bottom-inset, 0px) + env(safe-area-inset-bottom, 0px))
395
+ width: 58px
396
+ height: 58px
397
+ z-index: 1200
398
+ filter: drop-shadow(0 8px 18px rgba(0,0,0,0.2))
399
+
400
+ .d-back-to-top__progress,
401
+ .d-back-to-top__button
402
+ position: absolute
403
+ inset: 0
404
+
405
+ .d-back-to-top__button
406
+ margin: auto
407
+ width: 40px
408
+ height: 40px
409
+
324
410
  #scroll-container
325
411
  width: 100%
326
412
  max-width: 1200px
@@ -425,4 +511,12 @@ body.mobile.body--dark
425
511
  body.mobile
426
512
  .q-drawer--right
427
513
  background: rgba(255, 255, 255, 0.7)
514
+
515
+ body.body--light
516
+ .d-back-to-top__progress
517
+ color: var(--q-primary)
518
+
519
+ body.body--dark
520
+ .d-back-to-top__progress
521
+ color: #58d1a8
428
522
  </style>
@@ -0,0 +1,78 @@
1
+ <script setup>
2
+ defineProps({
3
+ title: {
4
+ type: String,
5
+ default: ''
6
+ },
7
+ open: {
8
+ type: Boolean,
9
+ default: false
10
+ }
11
+ })
12
+ </script>
13
+
14
+ <template>
15
+ <q-expansion-item
16
+ class="d-page-expandable"
17
+ switch-toggle-side
18
+ :default-opened="open"
19
+ header-class="d-page-expandable__header"
20
+ content-class="d-page-expandable__content"
21
+ >
22
+ <template #header>
23
+ <q-item-section>
24
+ <div class="d-page-expandable__title">{{ title }}</div>
25
+ </q-item-section>
26
+ </template>
27
+
28
+ <div class="d-page-expandable__body">
29
+ <slot />
30
+ </div>
31
+ </q-expansion-item>
32
+ </template>
33
+
34
+ <style lang="sass">
35
+ body.body--light
36
+ --d-page-expandable-bg: #faf8f2
37
+ --d-page-expandable-border: rgba(116, 92, 46, 0.18)
38
+ --d-page-expandable-divider: rgba(116, 92, 46, 0.12)
39
+ --d-page-expandable-shadow: rgba(116, 92, 46, 0.08)
40
+
41
+ body.body--dark
42
+ --d-page-expandable-bg: rgba(255, 248, 235, 0.035)
43
+ --d-page-expandable-border: rgba(255, 235, 194, 0.14)
44
+ --d-page-expandable-divider: rgba(255, 235, 194, 0.08)
45
+ --d-page-expandable-shadow: rgba(0, 0, 0, 0.28)
46
+
47
+ .d-page-expandable
48
+ margin: 1.5rem 0
49
+ border: 1px solid var(--d-page-expandable-border)
50
+ border-radius: 16px
51
+ overflow: hidden
52
+ background: var(--d-page-expandable-bg)
53
+ box-shadow: 0 14px 32px var(--d-page-expandable-shadow)
54
+
55
+ .q-item
56
+ min-height: 0
57
+ padding: 0
58
+
59
+ .q-item__section--side
60
+ padding-left: 0.55rem
61
+
62
+ .d-page-expandable__header
63
+ padding: 0.95rem 1rem
64
+
65
+ .d-page-expandable__title
66
+ font-size: 1rem
67
+ font-weight: 700
68
+ line-height: 1.45
69
+
70
+ .d-page-expandable__body
71
+ padding: 1rem 1rem 1.1rem
72
+
73
+ > :first-child
74
+ margin-top: 0
75
+
76
+ > :last-child
77
+ margin-bottom: 0
78
+ </style>