@masmarino/gabarit 1.4.0 → 2.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 (348) hide show
  1. package/README.md +231 -144
  2. package/accordion/README.md +56 -0
  3. package/alert/README.md +87 -0
  4. package/app-shell/README.md +133 -0
  5. package/auth/README.md +155 -0
  6. package/auth-activate/README.md +119 -0
  7. package/auth-login/README.md +113 -0
  8. package/auth-register/README.md +104 -0
  9. package/auth-reset-password/README.md +120 -0
  10. package/autocomplete/README.md +77 -0
  11. package/avatar/README.md +34 -0
  12. package/avatar-group/README.md +47 -0
  13. package/badge/README.md +177 -0
  14. package/bar-chart/README.md +44 -0
  15. package/breadcrumb/README.md +38 -0
  16. package/button/README.md +175 -0
  17. package/card/README.md +179 -0
  18. package/checkbox/README.md +50 -0
  19. package/checkbox-group/README.md +78 -0
  20. package/confirm-danger-modal/README.md +77 -0
  21. package/copy-button/README.md +90 -0
  22. package/copy-field/README.md +54 -0
  23. package/date-picker/README.md +84 -0
  24. package/description-list/README.md +63 -0
  25. package/dimension-card/README.md +39 -0
  26. package/disclosure/README.md +48 -0
  27. package/divider/README.md +31 -0
  28. package/drawer/README.md +49 -0
  29. package/empty-state/README.md +84 -0
  30. package/fesm2022/masmarino-gabarit-accordion.mjs +243 -0
  31. package/fesm2022/masmarino-gabarit-accordion.mjs.map +1 -0
  32. package/fesm2022/masmarino-gabarit-alert.mjs +208 -0
  33. package/fesm2022/masmarino-gabarit-alert.mjs.map +1 -0
  34. package/fesm2022/masmarino-gabarit-app-shell.mjs +378 -0
  35. package/fesm2022/masmarino-gabarit-app-shell.mjs.map +1 -0
  36. package/fesm2022/masmarino-gabarit-auth-activate.mjs +415 -0
  37. package/fesm2022/masmarino-gabarit-auth-activate.mjs.map +1 -0
  38. package/fesm2022/masmarino-gabarit-auth-login.mjs +467 -0
  39. package/fesm2022/masmarino-gabarit-auth-login.mjs.map +1 -0
  40. package/fesm2022/masmarino-gabarit-auth-register.mjs +457 -0
  41. package/fesm2022/masmarino-gabarit-auth-register.mjs.map +1 -0
  42. package/fesm2022/masmarino-gabarit-auth-reset-password.mjs +364 -0
  43. package/fesm2022/masmarino-gabarit-auth-reset-password.mjs.map +1 -0
  44. package/fesm2022/masmarino-gabarit-auth.mjs +844 -0
  45. package/fesm2022/masmarino-gabarit-auth.mjs.map +1 -0
  46. package/fesm2022/masmarino-gabarit-autocomplete.mjs +477 -0
  47. package/fesm2022/masmarino-gabarit-autocomplete.mjs.map +1 -0
  48. package/fesm2022/masmarino-gabarit-avatar-group.mjs +199 -0
  49. package/fesm2022/masmarino-gabarit-avatar-group.mjs.map +1 -0
  50. package/fesm2022/masmarino-gabarit-avatar.mjs +107 -0
  51. package/fesm2022/masmarino-gabarit-avatar.mjs.map +1 -0
  52. package/fesm2022/masmarino-gabarit-badge.mjs +449 -0
  53. package/fesm2022/masmarino-gabarit-badge.mjs.map +1 -0
  54. package/fesm2022/masmarino-gabarit-bar-chart.mjs +408 -0
  55. package/fesm2022/masmarino-gabarit-bar-chart.mjs.map +1 -0
  56. package/fesm2022/masmarino-gabarit-breadcrumb.mjs +59 -0
  57. package/fesm2022/masmarino-gabarit-breadcrumb.mjs.map +1 -0
  58. package/fesm2022/masmarino-gabarit-button.mjs +374 -0
  59. package/fesm2022/masmarino-gabarit-button.mjs.map +1 -0
  60. package/fesm2022/masmarino-gabarit-card.mjs +400 -0
  61. package/fesm2022/masmarino-gabarit-card.mjs.map +1 -0
  62. package/fesm2022/masmarino-gabarit-chart.mjs +1289 -0
  63. package/fesm2022/masmarino-gabarit-chart.mjs.map +1 -0
  64. package/fesm2022/masmarino-gabarit-checkbox-group.mjs +335 -0
  65. package/fesm2022/masmarino-gabarit-checkbox-group.mjs.map +1 -0
  66. package/fesm2022/masmarino-gabarit-checkbox.mjs +170 -0
  67. package/fesm2022/masmarino-gabarit-checkbox.mjs.map +1 -0
  68. package/fesm2022/masmarino-gabarit-confirm-danger-modal.mjs +387 -0
  69. package/fesm2022/masmarino-gabarit-confirm-danger-modal.mjs.map +1 -0
  70. package/fesm2022/masmarino-gabarit-copy-button.mjs +407 -0
  71. package/fesm2022/masmarino-gabarit-copy-button.mjs.map +1 -0
  72. package/fesm2022/masmarino-gabarit-copy-field.mjs +229 -0
  73. package/fesm2022/masmarino-gabarit-copy-field.mjs.map +1 -0
  74. package/fesm2022/masmarino-gabarit-date-picker.mjs +1238 -0
  75. package/fesm2022/masmarino-gabarit-date-picker.mjs.map +1 -0
  76. package/fesm2022/masmarino-gabarit-description-list.mjs +127 -0
  77. package/fesm2022/masmarino-gabarit-description-list.mjs.map +1 -0
  78. package/fesm2022/masmarino-gabarit-dimension-card.mjs +162 -0
  79. package/fesm2022/masmarino-gabarit-dimension-card.mjs.map +1 -0
  80. package/fesm2022/masmarino-gabarit-disclosure.mjs +154 -0
  81. package/fesm2022/masmarino-gabarit-disclosure.mjs.map +1 -0
  82. package/fesm2022/masmarino-gabarit-divider.mjs +90 -0
  83. package/fesm2022/masmarino-gabarit-divider.mjs.map +1 -0
  84. package/fesm2022/masmarino-gabarit-docs.mjs +21 -11
  85. package/fesm2022/masmarino-gabarit-docs.mjs.map +1 -1
  86. package/fesm2022/masmarino-gabarit-drawer.mjs +209 -0
  87. package/fesm2022/masmarino-gabarit-drawer.mjs.map +1 -0
  88. package/fesm2022/masmarino-gabarit-empty-state.mjs +226 -0
  89. package/fesm2022/masmarino-gabarit-empty-state.mjs.map +1 -0
  90. package/fesm2022/masmarino-gabarit-file-upload.mjs +335 -0
  91. package/fesm2022/masmarino-gabarit-file-upload.mjs.map +1 -0
  92. package/fesm2022/masmarino-gabarit-floating-panel.mjs +13 -0
  93. package/fesm2022/masmarino-gabarit-floating-panel.mjs.map +1 -0
  94. package/fesm2022/masmarino-gabarit-format.mjs +345 -0
  95. package/fesm2022/masmarino-gabarit-format.mjs.map +1 -0
  96. package/fesm2022/masmarino-gabarit-funnel-chart.mjs +247 -0
  97. package/fesm2022/masmarino-gabarit-funnel-chart.mjs.map +1 -0
  98. package/fesm2022/masmarino-gabarit-gauge-bar.mjs +180 -0
  99. package/fesm2022/masmarino-gabarit-gauge-bar.mjs.map +1 -0
  100. package/fesm2022/masmarino-gabarit-git-field.mjs +127 -0
  101. package/fesm2022/masmarino-gabarit-git-field.mjs.map +1 -0
  102. package/fesm2022/masmarino-gabarit-icon-marker.mjs +150 -0
  103. package/fesm2022/masmarino-gabarit-icon-marker.mjs.map +1 -0
  104. package/fesm2022/masmarino-gabarit-icon.mjs +308 -0
  105. package/fesm2022/masmarino-gabarit-icon.mjs.map +1 -0
  106. package/fesm2022/masmarino-gabarit-input.mjs +493 -0
  107. package/fesm2022/masmarino-gabarit-input.mjs.map +1 -0
  108. package/fesm2022/masmarino-gabarit-job-graph.mjs +216 -0
  109. package/fesm2022/masmarino-gabarit-job-graph.mjs.map +1 -0
  110. package/fesm2022/masmarino-gabarit-job-status.mjs +104 -0
  111. package/fesm2022/masmarino-gabarit-job-status.mjs.map +1 -0
  112. package/fesm2022/masmarino-gabarit-line-chart.mjs +574 -0
  113. package/fesm2022/masmarino-gabarit-line-chart.mjs.map +1 -0
  114. package/fesm2022/masmarino-gabarit-list-card.mjs +320 -0
  115. package/fesm2022/masmarino-gabarit-list-card.mjs.map +1 -0
  116. package/fesm2022/masmarino-gabarit-list-row.mjs +58 -0
  117. package/fesm2022/masmarino-gabarit-list-row.mjs.map +1 -0
  118. package/fesm2022/masmarino-gabarit-list-toolbar.mjs +369 -0
  119. package/fesm2022/masmarino-gabarit-list-toolbar.mjs.map +1 -0
  120. package/fesm2022/masmarino-gabarit-menu.mjs +461 -0
  121. package/fesm2022/masmarino-gabarit-menu.mjs.map +1 -0
  122. package/fesm2022/masmarino-gabarit-mfa-enrollment.mjs +897 -0
  123. package/fesm2022/masmarino-gabarit-mfa-enrollment.mjs.map +1 -0
  124. package/fesm2022/masmarino-gabarit-mfa-settings.mjs +629 -0
  125. package/fesm2022/masmarino-gabarit-mfa-settings.mjs.map +1 -0
  126. package/fesm2022/masmarino-gabarit-modal.mjs +260 -0
  127. package/fesm2022/masmarino-gabarit-modal.mjs.map +1 -0
  128. package/fesm2022/masmarino-gabarit-nav-tabs.mjs +332 -0
  129. package/fesm2022/masmarino-gabarit-nav-tabs.mjs.map +1 -0
  130. package/fesm2022/masmarino-gabarit-notification-dot.mjs +119 -0
  131. package/fesm2022/masmarino-gabarit-notification-dot.mjs.map +1 -0
  132. package/fesm2022/masmarino-gabarit-page-header.mjs +78 -0
  133. package/fesm2022/masmarino-gabarit-page-header.mjs.map +1 -0
  134. package/fesm2022/masmarino-gabarit-page-layout.mjs +157 -0
  135. package/fesm2022/masmarino-gabarit-page-layout.mjs.map +1 -0
  136. package/fesm2022/masmarino-gabarit-pagination.mjs +415 -0
  137. package/fesm2022/masmarino-gabarit-pagination.mjs.map +1 -0
  138. package/fesm2022/masmarino-gabarit-panel.mjs +80 -0
  139. package/fesm2022/masmarino-gabarit-panel.mjs.map +1 -0
  140. package/fesm2022/masmarino-gabarit-passkey-settings.mjs +606 -0
  141. package/fesm2022/masmarino-gabarit-passkey-settings.mjs.map +1 -0
  142. package/fesm2022/masmarino-gabarit-pie-chart.mjs +317 -0
  143. package/fesm2022/masmarino-gabarit-pie-chart.mjs.map +1 -0
  144. package/fesm2022/masmarino-gabarit-popover.mjs +139 -0
  145. package/fesm2022/masmarino-gabarit-popover.mjs.map +1 -0
  146. package/fesm2022/masmarino-gabarit-radio-group.mjs +202 -0
  147. package/fesm2022/masmarino-gabarit-radio-group.mjs.map +1 -0
  148. package/fesm2022/masmarino-gabarit-save-status.mjs +142 -0
  149. package/fesm2022/masmarino-gabarit-save-status.mjs.map +1 -0
  150. package/fesm2022/masmarino-gabarit-search-bar.mjs +576 -0
  151. package/fesm2022/masmarino-gabarit-search-bar.mjs.map +1 -0
  152. package/fesm2022/masmarino-gabarit-secret-reveal.mjs +348 -0
  153. package/fesm2022/masmarino-gabarit-secret-reveal.mjs.map +1 -0
  154. package/fesm2022/masmarino-gabarit-segmented-control.mjs +272 -0
  155. package/fesm2022/masmarino-gabarit-segmented-control.mjs.map +1 -0
  156. package/fesm2022/masmarino-gabarit-select.mjs +510 -0
  157. package/fesm2022/masmarino-gabarit-select.mjs.map +1 -0
  158. package/fesm2022/masmarino-gabarit-skeleton-list.mjs +189 -0
  159. package/fesm2022/masmarino-gabarit-skeleton-list.mjs.map +1 -0
  160. package/fesm2022/masmarino-gabarit-skeleton.mjs +109 -0
  161. package/fesm2022/masmarino-gabarit-skeleton.mjs.map +1 -0
  162. package/fesm2022/masmarino-gabarit-slider.mjs +239 -0
  163. package/fesm2022/masmarino-gabarit-slider.mjs.map +1 -0
  164. package/fesm2022/masmarino-gabarit-sparkline.mjs +276 -0
  165. package/fesm2022/masmarino-gabarit-sparkline.mjs.map +1 -0
  166. package/fesm2022/masmarino-gabarit-spinner.mjs +86 -0
  167. package/fesm2022/masmarino-gabarit-spinner.mjs.map +1 -0
  168. package/fesm2022/masmarino-gabarit-stat-grid.mjs +139 -0
  169. package/fesm2022/masmarino-gabarit-stat-grid.mjs.map +1 -0
  170. package/fesm2022/masmarino-gabarit-stat-tile.mjs +312 -0
  171. package/fesm2022/masmarino-gabarit-stat-tile.mjs.map +1 -0
  172. package/fesm2022/masmarino-gabarit-stepper.mjs +219 -0
  173. package/fesm2022/masmarino-gabarit-stepper.mjs.map +1 -0
  174. package/fesm2022/masmarino-gabarit-switch.mjs +151 -0
  175. package/fesm2022/masmarino-gabarit-switch.mjs.map +1 -0
  176. package/fesm2022/masmarino-gabarit-table.mjs +206 -0
  177. package/fesm2022/masmarino-gabarit-table.mjs.map +1 -0
  178. package/fesm2022/masmarino-gabarit-tabs.mjs +210 -0
  179. package/fesm2022/masmarino-gabarit-tabs.mjs.map +1 -0
  180. package/fesm2022/masmarino-gabarit-tag-input.mjs +288 -0
  181. package/fesm2022/masmarino-gabarit-tag-input.mjs.map +1 -0
  182. package/fesm2022/masmarino-gabarit-tag.mjs +155 -0
  183. package/fesm2022/masmarino-gabarit-tag.mjs.map +1 -0
  184. package/fesm2022/masmarino-gabarit-textarea.mjs +369 -0
  185. package/fesm2022/masmarino-gabarit-textarea.mjs.map +1 -0
  186. package/fesm2022/masmarino-gabarit-timeline-chart.mjs +521 -0
  187. package/fesm2022/masmarino-gabarit-timeline-chart.mjs.map +1 -0
  188. package/fesm2022/masmarino-gabarit-toaster.mjs +220 -0
  189. package/fesm2022/masmarino-gabarit-toaster.mjs.map +1 -0
  190. package/fesm2022/masmarino-gabarit-tooltip.mjs +182 -0
  191. package/fesm2022/masmarino-gabarit-tooltip.mjs.map +1 -0
  192. package/fesm2022/masmarino-gabarit-tree.mjs +258 -0
  193. package/fesm2022/masmarino-gabarit-tree.mjs.map +1 -0
  194. package/fesm2022/masmarino-gabarit-user-chip.mjs +106 -0
  195. package/fesm2022/masmarino-gabarit-user-chip.mjs.map +1 -0
  196. package/fesm2022/masmarino-gabarit.mjs +83 -24785
  197. package/fesm2022/masmarino-gabarit.mjs.map +1 -1
  198. package/file-upload/README.md +47 -0
  199. package/fonts/OFL-ibm-plex.txt +93 -0
  200. package/fonts/ibm-plex-mono-400.woff2 +0 -0
  201. package/fonts/ibm-plex-mono-500.woff2 +0 -0
  202. package/fonts/ibm-plex-sans-400.woff2 +0 -0
  203. package/fonts/ibm-plex-sans-500.woff2 +0 -0
  204. package/fonts/ibm-plex-sans-600.woff2 +0 -0
  205. package/fonts/ibm-plex-sans-condensed-600.woff2 +0 -0
  206. package/fonts/index.scss +28 -0
  207. package/funnel-chart/README.md +39 -0
  208. package/gauge-bar/README.md +35 -0
  209. package/git-field/README.md +34 -0
  210. package/icon/README.md +52 -0
  211. package/icon-marker/README.md +37 -0
  212. package/input/README.md +120 -0
  213. package/job-graph/README.md +76 -0
  214. package/job-status/README.md +34 -0
  215. package/line-chart/README.md +52 -0
  216. package/list-card/README.md +144 -0
  217. package/list-row/README.md +72 -0
  218. package/list-toolbar/README.md +52 -0
  219. package/menu/README.md +90 -0
  220. package/mfa-enrollment/README.md +189 -0
  221. package/mfa-settings/README.md +154 -0
  222. package/modal/README.md +72 -0
  223. package/nav-tabs/README.md +106 -0
  224. package/notification-dot/README.md +43 -0
  225. package/package.json +335 -1
  226. package/page-header/README.md +56 -0
  227. package/page-layout/README.md +76 -0
  228. package/pagination/README.md +73 -0
  229. package/panel/README.md +56 -0
  230. package/passkey-settings/README.md +120 -0
  231. package/pie-chart/README.md +85 -0
  232. package/popover/README.md +62 -0
  233. package/radio-group/README.md +47 -0
  234. package/save-status/README.md +44 -0
  235. package/search-bar/README.md +84 -0
  236. package/secret-reveal/README.md +60 -0
  237. package/segmented-control/README.md +79 -0
  238. package/select/README.md +61 -0
  239. package/skeleton/README.md +49 -0
  240. package/skeleton-list/README.md +40 -0
  241. package/slider/README.md +44 -0
  242. package/sparkline/README.md +37 -0
  243. package/spinner/README.md +41 -0
  244. package/src/lib/tokens/_a11y.scss +22 -0
  245. package/src/lib/tokens/_base.scss +31 -0
  246. package/src/lib/tokens/_palette.scss +52 -51
  247. package/src/lib/tokens/_semantic.scss +17 -124
  248. package/src/lib/tokens/_themes.scss +144 -0
  249. package/src/lib/tokens/_utilities.scss +10 -10
  250. package/src/lib/tokens/index.scss +3 -0
  251. package/stat-grid/README.md +47 -0
  252. package/stat-tile/README.md +75 -0
  253. package/stepper/README.md +67 -0
  254. package/switch/README.md +51 -0
  255. package/table/README.md +75 -0
  256. package/tabs/README.md +34 -0
  257. package/tag/README.md +34 -0
  258. package/tag-input/README.md +45 -0
  259. package/textarea/README.md +76 -0
  260. package/timeline-chart/README.md +49 -0
  261. package/toaster/README.md +92 -0
  262. package/tooltip/README.md +50 -0
  263. package/tree/README.md +79 -0
  264. package/types/masmarino-gabarit-accordion.d.ts +54 -0
  265. package/types/masmarino-gabarit-alert.d.ts +65 -0
  266. package/types/masmarino-gabarit-app-shell.d.ts +102 -0
  267. package/types/masmarino-gabarit-auth-activate.d.ts +70 -0
  268. package/types/masmarino-gabarit-auth-login.d.ts +63 -0
  269. package/types/masmarino-gabarit-auth-register.d.ts +66 -0
  270. package/types/masmarino-gabarit-auth-reset-password.d.ts +53 -0
  271. package/types/masmarino-gabarit-auth.d.ts +543 -0
  272. package/types/masmarino-gabarit-autocomplete.d.ts +139 -0
  273. package/types/masmarino-gabarit-avatar-group.d.ts +59 -0
  274. package/types/masmarino-gabarit-avatar.d.ts +31 -0
  275. package/types/masmarino-gabarit-badge.d.ts +139 -0
  276. package/types/masmarino-gabarit-bar-chart.d.ts +111 -0
  277. package/types/masmarino-gabarit-breadcrumb.d.ts +12 -0
  278. package/types/masmarino-gabarit-button.d.ts +108 -0
  279. package/types/masmarino-gabarit-card.d.ts +102 -0
  280. package/types/masmarino-gabarit-chart.d.ts +361 -0
  281. package/types/masmarino-gabarit-checkbox-group.d.ts +113 -0
  282. package/types/masmarino-gabarit-checkbox.d.ts +49 -0
  283. package/types/masmarino-gabarit-confirm-danger-modal.d.ts +94 -0
  284. package/types/masmarino-gabarit-copy-button.d.ts +111 -0
  285. package/types/masmarino-gabarit-copy-field.d.ts +64 -0
  286. package/types/masmarino-gabarit-date-picker.d.ts +397 -0
  287. package/types/masmarino-gabarit-description-list.d.ts +40 -0
  288. package/types/masmarino-gabarit-dimension-card.d.ts +55 -0
  289. package/types/masmarino-gabarit-disclosure.d.ts +44 -0
  290. package/types/masmarino-gabarit-divider.d.ts +20 -0
  291. package/types/masmarino-gabarit-docs.d.ts +20 -59
  292. package/types/masmarino-gabarit-drawer.d.ts +51 -0
  293. package/types/masmarino-gabarit-empty-state.d.ts +67 -0
  294. package/types/masmarino-gabarit-file-upload.d.ts +95 -0
  295. package/types/masmarino-gabarit-floating-panel.d.ts +7 -0
  296. package/types/masmarino-gabarit-format.d.ts +54 -0
  297. package/types/masmarino-gabarit-funnel-chart.d.ts +78 -0
  298. package/types/masmarino-gabarit-gauge-bar.d.ts +54 -0
  299. package/types/masmarino-gabarit-git-field.d.ts +39 -0
  300. package/types/masmarino-gabarit-icon-marker.d.ts +47 -0
  301. package/types/masmarino-gabarit-icon.d.ts +23 -0
  302. package/types/masmarino-gabarit-input.d.ts +181 -0
  303. package/types/masmarino-gabarit-job-graph.d.ts +63 -0
  304. package/types/masmarino-gabarit-job-status.d.ts +20 -0
  305. package/types/masmarino-gabarit-line-chart.d.ts +153 -0
  306. package/types/masmarino-gabarit-list-card.d.ts +87 -0
  307. package/types/masmarino-gabarit-list-row.d.ts +14 -0
  308. package/types/masmarino-gabarit-list-toolbar.d.ts +100 -0
  309. package/types/masmarino-gabarit-menu.d.ts +92 -0
  310. package/types/masmarino-gabarit-mfa-enrollment.d.ts +142 -0
  311. package/types/masmarino-gabarit-mfa-settings.d.ts +89 -0
  312. package/types/masmarino-gabarit-modal.d.ts +60 -0
  313. package/types/masmarino-gabarit-nav-tabs.d.ts +65 -0
  314. package/types/masmarino-gabarit-notification-dot.d.ts +34 -0
  315. package/types/masmarino-gabarit-page-header.d.ts +20 -0
  316. package/types/masmarino-gabarit-page-layout.d.ts +46 -0
  317. package/types/masmarino-gabarit-pagination.d.ts +109 -0
  318. package/types/masmarino-gabarit-panel.d.ts +21 -0
  319. package/types/masmarino-gabarit-passkey-settings.d.ts +94 -0
  320. package/types/masmarino-gabarit-pie-chart.d.ts +94 -0
  321. package/types/masmarino-gabarit-popover.d.ts +32 -0
  322. package/types/masmarino-gabarit-radio-group.d.ts +66 -0
  323. package/types/masmarino-gabarit-save-status.d.ts +39 -0
  324. package/types/masmarino-gabarit-search-bar.d.ts +183 -0
  325. package/types/masmarino-gabarit-secret-reveal.d.ts +95 -0
  326. package/types/masmarino-gabarit-segmented-control.d.ts +76 -0
  327. package/types/masmarino-gabarit-select.d.ts +145 -0
  328. package/types/masmarino-gabarit-skeleton-list.d.ts +54 -0
  329. package/types/masmarino-gabarit-skeleton.d.ts +26 -0
  330. package/types/masmarino-gabarit-slider.d.ts +73 -0
  331. package/types/masmarino-gabarit-sparkline.d.ts +70 -0
  332. package/types/masmarino-gabarit-spinner.d.ts +20 -0
  333. package/types/masmarino-gabarit-stat-grid.d.ts +39 -0
  334. package/types/masmarino-gabarit-stat-tile.d.ts +79 -0
  335. package/types/masmarino-gabarit-stepper.d.ts +67 -0
  336. package/types/masmarino-gabarit-switch.d.ts +42 -0
  337. package/types/masmarino-gabarit-table.d.ts +60 -0
  338. package/types/masmarino-gabarit-tabs.d.ts +40 -0
  339. package/types/masmarino-gabarit-tag-input.d.ts +78 -0
  340. package/types/masmarino-gabarit-tag.d.ts +35 -0
  341. package/types/masmarino-gabarit-textarea.d.ts +109 -0
  342. package/types/masmarino-gabarit-timeline-chart.d.ts +145 -0
  343. package/types/masmarino-gabarit-toaster.d.ts +62 -0
  344. package/types/masmarino-gabarit-tooltip.d.ts +38 -0
  345. package/types/masmarino-gabarit-tree.d.ts +71 -0
  346. package/types/masmarino-gabarit-user-chip.d.ts +26 -0
  347. package/types/masmarino-gabarit.d.ts +83 -6605
  348. package/user-chip/README.md +42 -0
@@ -0,0 +1,87 @@
1
+ # Alert
2
+
3
+ Persistent inline message — a banner within a page or section, not a
4
+ transient notification. Distinct from `Toaster` (auto-dismissing,
5
+ stacked at a screen corner): `Alert` stays visible for as long as the
6
+ app renders it.
7
+
8
+ **Selector**: `gbt-alert`
9
+
10
+ ## Inputs
11
+
12
+ | Input | Type | Default | Role |
13
+ | ------------- | ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
14
+ | `variant` | `AlertVariant` | `'info'` | `'info' \| 'success' \| 'warning' \| 'error' \| 'neutral'` (`neutral`: a quiet grey status line or review bar). |
15
+ | `dismissible` | `boolean` | `false` | Shows a close button. |
16
+ | `closeLabel` | `string` | `'Dismiss'` | Accessible name of the close button. |
17
+ | `live` | `AlertLive` | `'auto'` | `'auto' \| 'assertive' \| 'polite' \| 'off'` — how the alert is announced (see _Role_). |
18
+ | `heading` | `string` | `''` | A short bold title above the message. |
19
+ | `size` | `AlertSize` | `'md'` | `'md' \| 'sm'` — `sm` is the tighter alert for side panels, hints and dense cards. |
20
+ | `appearance` | `AlertAppearance` | `'default'` | `'default' \| 'subtle'` — subtle: lighter wash, hairline edge and icon ring. |
21
+ | `iconAlign` | `AlertIconAlign` | `'auto'` | `'auto' \| 'center' \| 'start'` — `auto` centres the icon on a single block and moves it to the first line once there is a `heading` or `[alert-actions]`; `start` forces the top, `center` opts out. |
22
+
23
+ ## Outputs
24
+
25
+ | Output | Type | Role |
26
+ | ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | `dismissed` | `void` | Emitted when the close button is clicked — `Alert` does not remove itself, like `Toaster`'s own close button; the app decides whether to stop rendering it. |
28
+
29
+ ## Content
30
+
31
+ The message comes from projected content (`<ng-content />`), so it can
32
+ include an action link, not just plain text.
33
+
34
+ `[alert-actions]` projects buttons or links into a slot beside
35
+ the message — they share the row while there is room and drop under the
36
+ message when there is not:
37
+
38
+ ```html
39
+ <gbt-alert variant="error">
40
+ Les variables n'ont pas pu être chargées.
41
+ <gbt-button alert-actions variant="secondary" size="small" text="Réessayer" (clicked)="retry()" />
42
+ </gbt-alert>
43
+
44
+ <gbt-alert variant="error" heading="Impossible de charger le tableau de bord">
45
+ Le service de métriques ne répond pas.
46
+ <gbt-button alert-actions variant="secondary" size="small" text="Réessayer" />
47
+ </gbt-alert>
48
+ ```
49
+
50
+ ## Example
51
+
52
+ ```html
53
+ <gbt-alert variant="warning">Le quota du dépôt est presque atteint.</gbt-alert>
54
+
55
+ <gbt-alert variant="error" [dismissible]="true" closeLabel="Fermer" (dismissed)="showError = false">
56
+ Le paiement a échoué. <a href="/facturation">Mettre à jour le moyen de paiement</a>
57
+ </gbt-alert>
58
+ ```
59
+
60
+ ## Role and `live`
61
+
62
+ With the default `live="auto"`, `warning` and `error` use `role="alert"`
63
+ (announced immediately), `info`, `success` and `neutral` use `role="status"`
64
+ (announced politely) — the same split `Toaster` already uses for its
65
+ variants.
66
+
67
+ `live` overrides that mapping:
68
+
69
+ | `live` | Result |
70
+ | ------------- | ----------------------------------------------------------- |
71
+ | `'auto'` | The mapping above (default). |
72
+ | `'assertive'` | `role="alert"` whatever the variant. |
73
+ | `'polite'` | `role="status"` whatever the variant. |
74
+ | `'off'` | No `role`, no `aria-live`, no `aria-atomic`: a static note. |
75
+
76
+ A live region only announces what appears **after** the page has loaded.
77
+ A note that is on the page from the start (a warning above a form, a
78
+ footnote) should be `live="off"`, otherwise a static `warning` interrupts
79
+ screen-reader users for nothing. A message that appears as the result of an
80
+ action (a failed save, a load error) keeps `auto`, or `polite` when it is
81
+ not urgent. Never nest an alert inside another live region.
82
+
83
+ ## Touch
84
+
85
+ The close button is 44 × 44 px on coarse pointers
86
+ (`@media (pointer: coarse)`); the alert keeps its height, only the hit area
87
+ and the focus ring grow.
@@ -0,0 +1,133 @@
1
+ # AppShell
2
+
3
+ Page shell — side navigation panel, header, content. Below the 768px
4
+ breakpoint, the navigation becomes a drawer: the button opens it, the
5
+ backdrop or Escape closes it, focus is trapped inside while it's open
6
+ and returns to the button on close.
7
+
8
+ The header and the navigation are held to the window: while a long page
9
+ scrolls, both stay in view, so the version and the collapse toggle are
10
+ always in reach. Links that outgrow the window scroll inside the
11
+ navigation, under its bottom (version and toggle), which stays put.
12
+
13
+ **Selector**: `gbt-app-shell`
14
+
15
+ ## Inputs
16
+
17
+ | Input | Type | Role |
18
+ | ---------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | `navLabel` | `string` | Required. Accessible name of the navigation (`<nav aria-label>`). |
20
+ | `skipLabel` | `string` | Required. Text of the skip link to the content. |
21
+ | `openMenuLabel` | `string` | Required. Accessible name of the button, drawer closed. |
22
+ | `closeMenuLabel` | `string` | Required. Accessible name of the button, drawer open. |
23
+ | `collapseLabel` | `string` | Required if `collapsible` is `true`. Accessible name of the collapse-toggle button, nav expanded. |
24
+ | `expandLabel` | `string` | Required if `collapsible` is `true`. Accessible name of the collapse-toggle button, nav collapsed. |
25
+ | `collapsed` | `boolean` | Optional, defaults to `false`. Fully controlled — `AppShell` never persists it; bind `[(collapsed)]` to a signal you own if you want it remembered across sessions. Only has an effect at/above the 768px breakpoint. |
26
+ | `collapsible` | `boolean` | Optional, defaults to `true`. Set to `false` to omit the built-in collapse-toggle button entirely — e.g. if your app drives `collapsed` from its own control elsewhere. When `false`, `collapseLabel`/`expandLabel` aren't needed. |
27
+
28
+ ## Outputs
29
+
30
+ | Output | Type | Role |
31
+ | ----------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------- |
32
+ | `collapsedChange` | `boolean` | Emitted when the collapse-toggle button is clicked, with the new desired value — `AppShell` does not update `collapsed` itself. |
33
+
34
+ ## Projected content
35
+
36
+ | Selector | Role |
37
+ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | `[shell-brand]` | The brand, at the top of the navigation. With `collapsed`, plain text is clipped with an ellipsis rather than overflowing the rail — but since you already own the `collapsed` signal you bind to `[collapsed]`/`(collapsedChange)`, prefer swapping in a compact icon yourself (see example below) over relying on the ellipsis. |
39
+ | `[shell-nav]` | The navigation links. `.gbt-app-shell__link` (in `_utilities.scss`) for styling; `aria-current="page"` denotes the current page — never a class alone. When using `collapsed`, each link's structure must be `<gbt-icon .../><span>Label</span>` — the icon stays visible in the rail, and the `<span>` is what the hover/focus flyout reveals. For a collapsible group of links, see [`gbt-app-shell-nav-group`](app-shell-nav-group/README.md). |
40
+ | `[shell-header]` | Header content: title, search, account menu… Several elements can project into this same slot. |
41
+ | Default | The page content, in a focusable `<main>`. |
42
+
43
+ **The collapsed rail's flyout.** In the 64 px rail a link shows only its icon; on hover or keyboard focus its
44
+ `<span>` label appears to the right of the rail, in a small bordered bubble (`--text-primary` on `--bg-principal`,
45
+ above the header and the page). The bubble sits outside the link and the rail, so the collapsed rail and its links
46
+ do not clip their box (`overflow: visible`); expanded, and in the mobile drawer, they do clip. A link that is not
47
+ the `<gbt-icon /><span>` structure (text only, a badge outside the span) spills over the page in the collapsed
48
+ rail: give every collapsible link that structure. The bubble opens on a real hover only (`@media (hover: hover)`: a
49
+ tap on a touch screen does not leave it painted over the page) and on keyboard focus; a bridge in front of it lets
50
+ the pointer travel from the link onto the label without the flyout closing.
51
+
52
+ `.gbt-app-shell` sets the background (`--bg-panel`) of the whole page,
53
+ content included — cards and other surfaces left on `--bg-principal`
54
+ stand out from it by contrast. `.gbt-container` (in `_utilities.scss`)
55
+ centers content at reading width, to place on the default-projected
56
+ content if needed.
57
+
58
+ ## Example
59
+
60
+ ```html
61
+ <gbt-app-shell
62
+ navLabel="Navigation principale"
63
+ skipLabel="Aller au contenu principal"
64
+ openMenuLabel="Ouvrir la navigation"
65
+ closeMenuLabel="Fermer la navigation"
66
+ collapseLabel="Réduire la navigation"
67
+ expandLabel="Agrandir la navigation"
68
+ >
69
+ <a shell-brand href="/">Hangar</a>
70
+ <a shell-nav href="/depots" class="gbt-app-shell__link" aria-current="page">Dépôts</a>
71
+ <a shell-nav href="/utilisateurs" class="gbt-app-shell__link">Utilisateurs</a>
72
+ <h1 shell-header>Dépôts</h1>
73
+ <div shell-header style="margin-left:auto">
74
+ <gbt-menu label="Mon compte" align="end">...</gbt-menu>
75
+ </div>
76
+
77
+ <p>Contenu de la page.</p>
78
+ </gbt-app-shell>
79
+ ```
80
+
81
+ With `collapsed` bound, each `[shell-nav]` link must use the `<gbt-icon
82
+ .../><span>Label</span>` structure described in the table above, so the
83
+ hover/focus flyout has a label to reveal. Since you already own the
84
+ `sidebarCollapsed` signal to drive `[collapsed]`/`(collapsedChange)`, reuse
85
+ it in `[shell-brand]` to swap in a compact logo yourself — no extra input
86
+ or output needed on `AppShell` for this:
87
+
88
+ ```html
89
+ <gbt-app-shell
90
+ navLabel="Navigation principale"
91
+ skipLabel="Aller au contenu principal"
92
+ openMenuLabel="Ouvrir la navigation"
93
+ closeMenuLabel="Fermer la navigation"
94
+ collapseLabel="Réduire la navigation"
95
+ expandLabel="Agrandir la navigation"
96
+ [collapsed]="sidebarCollapsed()"
97
+ (collapsedChange)="sidebarCollapsed.set($event)"
98
+ >
99
+ <a shell-brand href="/" aria-label="Hangar">
100
+ @if (sidebarCollapsed()) {
101
+ <gbt-icon name="logo-mark" />
102
+ } @else {
103
+ <gbt-icon name="logo-full" />
104
+ <span>Hangar</span>
105
+ }
106
+ </a>
107
+ <a shell-nav href="/depots" class="gbt-app-shell__link" aria-current="page">
108
+ <gbt-icon name="folder" />
109
+ <span>Dépôts</span>
110
+ </a>
111
+ <h1 shell-header>Dépôts</h1>
112
+ <p>Le contenu de la page.</p>
113
+ </gbt-app-shell>
114
+ ```
115
+
116
+ With `[collapsible]="false"`, the built-in button is omitted — `collapseLabel`/
117
+ `expandLabel` become unnecessary, and `collapsed`/`(collapsedChange)` stay
118
+ available if you drive the state from your own control elsewhere:
119
+
120
+ ```html
121
+ <gbt-app-shell
122
+ navLabel="Navigation principale"
123
+ skipLabel="Aller au contenu principal"
124
+ openMenuLabel="Ouvrir la navigation"
125
+ closeMenuLabel="Fermer la navigation"
126
+ [collapsible]="false"
127
+ >
128
+ <a shell-brand href="/">Hangar</a>
129
+ <a shell-nav href="/depots" class="gbt-app-shell__link" aria-current="page">Dépôts</a>
130
+ <h1 shell-header>Dépôts</h1>
131
+ <p>Le contenu de la page.</p>
132
+ </gbt-app-shell>
133
+ ```
package/auth/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # Auth kit
2
+
3
+ The public sign-in pages and the account's second-factor settings, as components an application uses
4
+ as they are: login (with the MFA challenge), free registration, invitation activation, the new
5
+ password after an administrator's reset, the mandatory
6
+ first MFA enrolment (authenticator app or passkey, then backup codes), and the account cards for the
7
+ authenticator app and the passkeys. Every application that uses them gets the same behaviour, the same
8
+ accessibility and the same look, by construction.
9
+
10
+ The kit is **router-agnostic** (it never imports `@angular/router`: it emits outputs and shows the
11
+ links the application projects), **backend-agnostic** (it never talks HTTP: every call goes through a
12
+ port the application implements), **storage-agnostic** (it never touches `localStorage`: sessions are
13
+ the port's business) and **locale-agnostic** (every string is a label with an English default).
14
+
15
+ | Component | Selector | Port |
16
+ | --------------------------------------------------------- | ---------------------- | ---------------------------------------- |
17
+ | [`AuthLogin`](../auth-login/README.md) | `gbt-auth-login` | `AUTH_PORT` |
18
+ | [`AuthRegister`](../auth-register/README.md) | `gbt-auth-register` | `AUTH_PORT` |
19
+ | [`AuthActivate`](../auth-activate/README.md) | `gbt-auth-activate` | `AUTH_PORT` |
20
+ | [`AuthResetPassword`](../auth-reset-password/README.md) | `gbt-auth-reset-password` | `AUTH_PORT` |
21
+ | [`MfaEnrollment`](../mfa-enrollment/README.md) | `gbt-mfa-enrollment` | `AUTH_PORT` |
22
+ | [`MfaSettings`](../mfa-settings/README.md) | `gbt-mfa-settings` | `MFA_PORT` |
23
+ | [`PasskeySettings`](../passkey-settings/README.md) | `gbt-passkey-settings` | `MFA_PORT` (and `AUTH_PORT` if provided) |
24
+ | [`AuthPanel`](auth-panel/README.md) | `gbt-auth-panel` | — |
25
+ | [`AuthFooter`, `AuthFooterLink`](auth-footer/README.md) | `gbt-auth-footer` | — |
26
+ | [`TotpQr`](../mfa-enrollment/totp-qr/README.md) | `gbt-totp-qr` | — (`TOTP_QR_RENDERER`) |
27
+ | [`BackupCodes`](../mfa-enrollment/backup-codes/README.md) | `gbt-backup-codes` | — |
28
+
29
+ ## Wiring
30
+
31
+ ```ts
32
+ // app.config.ts
33
+ providers: [
34
+ { provide: AUTH_PORT, useExisting: AuthService }, // your service implements AuthPort
35
+ { provide: MFA_PORT, useExisting: MfaService }, // your service implements MfaPort
36
+ {
37
+ provide: TOTP_QR_RENDERER, // Gabarit ships no QR encoder: bring one, loaded lazily
38
+ useValue: (text: string, options: TotpQrRenderOptions) =>
39
+ import('qrcode').then((qr) => qr.toDataURL(text, options)),
40
+ },
41
+ provideAuthLabels(MY_AUTH_LABELS), // optional: localise the whole kit once
42
+ ]
43
+ ```
44
+
45
+ > **Security: `TOTP_QR_RENDERER` receives the user's TOTP secret.** It is called with the full
46
+ > `otpauth://…?secret=…` URL, raw secret included. The renderer **must encode locally**, in the
47
+ > browser (a bundled library such as `qrcode`, as above): **no network call, never a hosted or
48
+ > third-party QR service** (a `https://…?data=otpauth…` image would hand every user's second factor
49
+ > to that service and its access logs). It **must not log** the text, nor send it to analytics or
50
+ > error reports. See [TotpQr](../mfa-enrollment/totp-qr/README.md).
51
+
52
+ ```html
53
+ <!-- login.page.html: a thin wrapper, routed at /login -->
54
+ <gbt-auth-login (loggedIn)="router.navigateByUrl('/home')">
55
+ <img auth-logo src="logo.svg" alt="Acme" width="480" height="120" />
56
+ <a gbtButton variant="link" gbtAuthFooterLink routerLink="/register">Create an account</a>
57
+ </gbt-auth-login>
58
+ ```
59
+
60
+ Every page takes the application's logo in its `[auth-logo]` slot (an `img`, a `picture` or an
61
+ `svg`) and the link of its footer in `[gbtAuthFooterLink]` (an `a[gbtButton]` in its `link` variant,
62
+ carrying the application's `routerLink` or `href`). A page without a projected footer link shows no
63
+ footer.
64
+
65
+ **`gbt-auth-register`, `gbt-auth-activate` and `gbt-auth-reset-password` also emit `(signIn)`**, from
66
+ their own terminal states (registration closed, account created, activation succeeded, password
67
+ changed, dead link), where "Sign in" is a button
68
+ rather than the projected link. That output is in addition to the projected `[gbtAuthFooterLink]`,
69
+ not instead of it: **wire both** (`(signIn)="router.navigateByUrl('/login')"` and the footer link)
70
+ for every path to reach the sign-in page.
71
+
72
+ ## The `AuthPort` contract
73
+
74
+ - **Sessions.** `login`, `register`, `verifyMfa` and `finishPasskeyChallenge` store the session they
75
+ obtain, when there is one (`LoginResponse.token` not null), then the page emits its success output.
76
+ `confirmTotp` and `finishPasskeySetup` must **not** store theirs: the enrolment holds the session
77
+ back until the user has acknowledged the backup codes (shown once), then the page hands it to
78
+ `setToken(token)` and emits.
79
+ - **MFA.** A `LoginResponse` with `token: null` and an `mfaToken` sends the user to the challenge
80
+ (`mfaHasTotp`, `mfaHasPasskey` say what they can use) or, with `mfaSetupRequired`, to the mandatory
81
+ enrolment.
82
+ - **Configuration.** `authConfig()` is read once by the login page (a failed read hides the
83
+ registration link; passkeys stay "unknown", which does not block them) and by the registration page
84
+ (a failed read shows the form: the server has the last word).
85
+
86
+ ## The error contract
87
+
88
+ A failed port call errors with `{ status, error }`: the HTTP status and the response body, the shape
89
+ of Angular's `HttpErrorResponse` (an adapter on `HttpClient` passes its errors through untouched). A
90
+ browser's WebAuthn error (a `DOMException`, no `status`) is told apart from a server answer by that
91
+ shape. The kit words every failure itself; the server's text is never shown. What it recognises
92
+ (`AUTH_PORT_ERROR_BODIES` holds the strings):
93
+
94
+ | Call | Answer | Read as |
95
+ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
96
+ | `login` | 401 | wrong username or password (any other failure: "sign-in failed") |
97
+ | any | 429 | too many attempts |
98
+ | MFA calls with an `mfaToken` | 401 `invalid or expired token` | the sign-in expired: back to the credentials |
99
+ | `verifyMfa`, `finishPasskeyChallenge` | 401 (any other body) | wrong code / passkey refused |
100
+ | `confirmTotp`, `confirm` | 400 `invalid code` | wrong code |
101
+ | enrolment calls | 400 `MFA is already set up` | the account got a factor meanwhile: back to the credentials |
102
+ | passkey calls | 503 | passkeys not available on this server |
103
+ | `finishPasskeySetup`, registration | 409 | this key is already registered |
104
+ | password-gated `MfaPort` calls | 400 `current password is incorrect` (exactly) | wrong password (never a 401, which an interceptor would take for a sign-out) |
105
+ | `startPasskeyRegistration`/`finish…` | 400 `too many passkeys` | the account holds the most passkeys the server keeps |
106
+ | `deletePasskey` | 404 | already gone: removed from the list, nobody signed out |
107
+ | `register` | 400 `registration is disabled` | the closed state |
108
+ | `register` | 400 `username is reserved` / `username …` / `email is not a valid address` / `password must be at least …` / other | the field concerned, else "check the fields" |
109
+ | `register` | 409 `email already in use` / other 409 | address taken / name taken |
110
+ | `activate`, `resetPassword` | 400 `password must be at least …` / other 400 | weak password (the link still works) / dead link |
111
+
112
+ An adapter for a backend that words these differently maps its answers onto them with `catchError`.
113
+
114
+ ## Session revocation
115
+
116
+ `MfaPort.disable` and `MfaPort.deletePasskey` revoke the caller's own session on the server (MFA
117
+ being mandatory, removing a factor signs every device out). The cards then emit `sessionRevoked`:
118
+ the application must discard its local session and go to its sign-in page. As a safety net, the card
119
+ that revoked the session also turns inert ("You have been signed out", its `signedOut` label, and no
120
+ action left), so an unbound output never leaves a live card acting on a dead session; it cannot clear
121
+ the application's stored session, though: binding `sessionRevoked` stays mandatory.
122
+
123
+ ## Activation and password-reset links
124
+
125
+ The mail should carry the token in the URL fragment (`/activate#token=…`,
126
+ `/reset-password#token=…`), which no server ever sees. The application's wrapper reads it once with
127
+ `activationToken(fragment, query)`, removes it from the address bar and history
128
+ (`navigateByUrl('/activate', { replaceUrl: true })`), and hands it to the `token` input of
129
+ `gbt-auth-activate` or `gbt-auth-reset-password`.
130
+
131
+ **The `token` input must be a one-time snapshot of the URL, never a value that reactively follows the
132
+ URL (e.g. a signal derived from `route.fragment`): the component resets when it changes.** Scrubbing
133
+ the URL would otherwise turn the token into `null` and flip the page to the dead-link view, even over
134
+ its success view.
135
+
136
+ ## Labels
137
+
138
+ Each component has a `labels` input (a partial object) over `provideAuthLabels({ … })` over its
139
+ English defaults (`DEFAULT_LOGIN_LABELS`, …); nested pieces (`gbt-mfa-enrollment` inside the login
140
+ page, `gbt-totp-qr` and `gbt-backup-codes` inside the enrolment and the settings) read the provided
141
+ labels, so an application localises the whole kit in one place. Interpolated strings are functions
142
+ (`step(current, total)`, `codesLeft(count)`, `passkeyAdded(name)`…).
143
+
144
+ ## The account cards together
145
+
146
+ `gbt-mfa-settings` and `gbt-passkey-settings` are meant to sit side by side. They share
147
+ `MfaSettingsState` (root-provided; provide it on a page to scope it): the factors as last read or
148
+ changed by either card, so the app becomes optional as soon as a passkey is added and deleting the
149
+ only key is flagged as removing the last factor; and which card owns the open form, so a view never
150
+ shows two password prompts (two primary buttons) at once.
151
+
152
+ ## Theming
153
+
154
+ `--gbt-auth-panel-logo-width` (15rem) sizes the logo; `--gbt-auth-panel-logo-offset` (0) pulls it
155
+ up when the artwork has a transparent margin above its drawing.
@@ -0,0 +1,119 @@
1
+ # AuthActivate
2
+
3
+ The activation page of the auth kit: where the link of an invitation mail lands, outside the app shell,
4
+ in the sign-in panel ([`gbt-auth-panel`](../auth/auth-panel/auth-panel.ts)). The invited user chooses a
5
+ password; no session comes out of it: they sign in afterwards and are taken through the mandatory MFA
6
+ enrolment like everybody. It never talks HTTP, never reads the URL and never navigates: the backend is
7
+ the application's `AUTH_PORT`, the token is an input, and the page tells the application where to go
8
+ through its outputs.
9
+
10
+ **Selector**: `gbt-auth-activate`
11
+
12
+ ## Views
13
+
14
+ | View | What shows |
15
+ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | form | A token was given: "Activate your account", New password (with its hint), Confirm the password, one primary "Activate my account", then the projected sign-in link. |
17
+ | success | The server accepted: "Your account is activated", what comes next, one "Sign in" button. |
18
+ | invalid | No token (`null` or `''`), or the server refused it (unknown, expired or used): an error-toned state, "This link does not work", ask for a new invitation, one "Sign in". |
19
+
20
+ ## Inputs
21
+
22
+ | Input | Type | Default | Role |
23
+ | ------------------- | ------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
+ | `token` | `string \| null` | `null` | The invitation's token, as the application read it from its URL with `activationToken(fragment, query)`. `null` (or `''`) is the dead link, without any request. A new value starts the page over. |
25
+ | `labels` | `Partial<ActivateLabels>` | `{}` | Strings to change, over `provideAuthLabels({ activate })` and the English defaults (`DEFAULT_ACTIVATE_LABELS`). |
26
+ | `minPasswordLength` | `number` | `MIN_PASSWORD_LENGTH` (8) | The server's minimum password length, checked before the round trip; also worded in the hint and the errors. |
27
+ | `chooseUsername` | `boolean` | `false` | For servers where the administrator invites by e-mail only: a Username field comes first, and the invitee's choice is sent as `activate(token, password, username)`. |
28
+ | `usernamePattern` | `RegExp` | `USERNAME_PATTERN` | The server's username rule, checked before the round trip when `chooseUsername` is on. |
29
+
30
+ ## Outputs
31
+
32
+ | Output | Payload | Role |
33
+ | ----------- | ------- | -------------------------------------------------------------------------------- |
34
+ | `activated` | `void` | The server accepted the password: the success view shows. No session was opened. |
35
+ | `signIn` | `void` | "Sign in" was pressed in the success or dead-link view: go to the sign-in page. |
36
+
37
+ ## Slots
38
+
39
+ | Selector | Role |
40
+ | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | `[auth-logo]` | The application's logo (an `img`, `picture` or `svg`), on top of the panel. Optional. |
42
+ | `[auth-backdrop]` | What is drawn on the graphite page, behind the panel: `gbt-git-field`, the family's animated commit graph (`@masmarino/gabarit/git-field`). Optional. |
43
+ | `[gbtAuthFooterLink]` | The link to the sign-in page, under the form after "Is your account already active?". An `a gbtButton variant="link"` carrying `routerLink` or `href`. No footer when absent. |
44
+
45
+ ## Behaviour
46
+
47
+ - **The token.** The page sends it with the password (`activate(token, password)`) and never renders it
48
+ (not in the markup, not in a field). Once spent (success) or refused (a 400 other than a weak password),
49
+ it is dropped: the page does not send it again until a new `token` arrives.
50
+ - **The application's part** (it owns the URL): put the token in the link's **fragment**
51
+ (`/activate#token=…`) so that no server, proxy or access log ever sees it; read it once with
52
+ `activationToken(route.snapshot.fragment, route.snapshot.queryParamMap.get('token'))` (the query is only a
53
+ fallback for older links; a token not shaped like the server's is `null`); then remove it (and any other
54
+ parameter) from the address bar and the history entry, e.g.
55
+ `router.navigateByUrl('/activate', { replaceUrl: true })` after the first render, so it does not linger in
56
+ a screenshot or a shared tab.
57
+ - **The `token` input must be a one-time snapshot of the URL, never a value that reactively follows the
58
+ URL (e.g. a signal derived from `route.fragment`): the component resets when it changes.** Scrubbing the
59
+ URL as above would otherwise turn the token into `null` and flip the page to the dead-link view, even over
60
+ its success view. Read it into a plain field, as in the example below.
61
+ - **`chooseUsername`.** The intro becomes `introWithUsername`, the Username field (with `usernameHint`) comes
62
+ before the passwords and takes the first focus, and it is checked first (`usernameEmpty`,
63
+ `usernameInvalid`). The value is sent trimmed; the server keeps the final say: a 400 `username is reserved`
64
+ (`usernameReserved`), another 400 starting with `username ` (`usernameInvalid`) or a 409
65
+ (`usernameTaken`) keeps the form, in an alert, the focus in the Username field.
66
+ - **`minPasswordLength` must mirror the server's own rule.** It only spares a round trip: the server stays
67
+ the authority, and a looser value only moves the refusal to the server's answer.
68
+ - **Checks before the request.** Nothing is said while typing; after a first attempt the password rule and
69
+ the confirmation ("Confirm your password", "The passwords do not match") show under their fields, the
70
+ focus moves to the first wrong one, and the checks stay live.
71
+ - **Failures** are worded from the labels, in an alert, the focus back in the password field: a weak-password
72
+ 400 keeps the form (the link is still good), a 429 says to wait, anything else (5xx, network) says the
73
+ activation failed and the same token can be retried. Any other 400 (but the username ones, with
74
+ `chooseUsername`) is the dead link.
75
+ - **Focus**: the form starts in the new-password field; the success and dead-link views move the focus to
76
+ their `h1` (focusable by script, not a tab stop). The passwords are emptied when the server accepted or
77
+ refused the link.
78
+
79
+ ## Example
80
+
81
+ ```ts
82
+ // app.config.ts
83
+ providers: [
84
+ { provide: AUTH_PORT, useClass: HttpAuthPort }, // your adapter over HttpClient
85
+ provideAuthLabels({ activate: { signInPrompt: 'Already signed up?' } }),
86
+ ]
87
+ ```
88
+
89
+ ```ts
90
+ @Component({
91
+ imports: [AuthActivate, Button, AuthFooterLink, RouterLink],
92
+ template: `
93
+ <gbt-auth-activate [token]="token" (signIn)="router.navigateByUrl('/login')">
94
+ <img auth-logo src="/logo.svg" alt="Acme" width="160" height="40" />
95
+ <a gbtButton variant="link" gbtAuthFooterLink routerLink="/login">Sign in</a>
96
+ </gbt-auth-activate>
97
+ `,
98
+ })
99
+ export class ActivateRoute {
100
+ protected readonly router = inject(Router)
101
+ private readonly route = inject(ActivatedRoute)
102
+ // Read once, then scrubbed from the address bar and the history entry.
103
+ protected readonly token = activationToken(
104
+ this.route.snapshot.fragment,
105
+ this.route.snapshot.queryParamMap.get('token'),
106
+ )
107
+
108
+ constructor() {
109
+ const { fragment, queryParamMap } = this.route.snapshot
110
+ if (fragment !== null || queryParamMap.keys.length > 0) {
111
+ afterNextRender(() => void this.router.navigateByUrl('/activate', { replaceUrl: true }))
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ## Accessibility
118
+
119
+ See [AUDIT.md](AUDIT.md). The panel owns the page's `<main>` landmark and its `h1`.
@@ -0,0 +1,113 @@
1
+ # AuthLogin
2
+
3
+ The sign-in page of the auth kit, outside the app shell: the application's logo,
4
+ a heading, the username and password fields and one "Sign in" button; then,
5
+ when the password is accepted, the second factor. It is router-, storage- and
6
+ backend-agnostic: every call goes through the application's
7
+ [`AuthPort`](../auth/ports/auth.port.ts), and the page tells the application the
8
+ user is signed in with `loggedIn` (the application navigates).
9
+
10
+ **Selector**: `gbt-auth-login`
11
+
12
+ ## States
13
+
14
+ | State | When | What shows |
15
+ | ----------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | Credentials | On open, after "Back", after an expired second step. | "Sign in", the two fields, the submit button; the registration footer when registration is open and the application projected a link. |
17
+ | Challenge | `login` answered an `mfaToken` without `mfaSetupRequired`. | "Two-step verification", with what this user can do here: their passkey (when they have one and both the browser and the server can run it), the 6-digit code of their app (when they have one), and always a backup code. |
18
+ | Enrolment | `login` answered an `mfaToken` with `mfaSetupRequired` (no second factor yet). | "Two-factor authentication" and [`gbt-mfa-enrollment`](../mfa-enrollment/mfa-enrollment.ts) in a wider panel: the mandatory first set-up of an app or a passkey, then the backup codes. The session is only handed over once the user acknowledged the codes. |
19
+
20
+ ## Inputs
21
+
22
+ | Input | Type | Default | Role |
23
+ | -------- | ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
24
+ | `labels` | `Partial<LoginLabels>` | `{}` | Strings to change, string by string, over `provideAuthLabels({ login })` and the English defaults (`DEFAULT_LOGIN_LABELS`). |
25
+
26
+ The enrolment takes its strings from `provideAuthLabels({ mfaEnrollment, totpQr, backupCodes })`.
27
+
28
+ ## Outputs
29
+
30
+ | Output | Payload | Role |
31
+ | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32
+ | `loggedIn` | `void` | The user is signed in: the port stored the session (`login`, `verifyMfa`, `finishPasskeyChallenge`), or the page handed the held-back session of a finished enrolment to `AuthPort.setToken`. Navigate to the application. |
33
+
34
+ ## Slots
35
+
36
+ | Selector | Role |
37
+ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | `[auth-logo]` | The application's logo (an `img`, a `picture`, an `svg`) at the top of the panel, on every state. Give it its `alt`. |
39
+ | `[auth-backdrop]` | What is drawn on the graphite page, behind the panel: `gbt-git-field`, the family's animated commit graph (`@masmarino/gabarit/git-field`). Optional. |
40
+ | `[gbtAuthFooterLink]` | The link to the application's registration page (`<a gbtButton variant="link" gbtAuthFooterLink routerLink="/register">`). Shown under the form, after "No account yet?", only when `authConfig` says registration is open. |
41
+ | `[auth-notice]` | Something the application has to say before the credentials (a session that ended, a sign-in link that failed), e.g. a `gbt-alert`. First in the form, on the credentials step only. |
42
+
43
+ ## Providers
44
+
45
+ | Token | Required | Role |
46
+ | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
47
+ | `AUTH_PORT` | Yes | The backend: `authConfig`, `login`, `verifyMfa`, `startPasskeyChallenge`, `finishPasskeyChallenge`, `setToken`, and the enrolment's calls. |
48
+ | `TOTP_QR_RENDERER` | For the enrolment's QR | The QR encoder of the authenticator-app set-up. Without one the enrolment shows the secret to type by hand. |
49
+ | `AUTH_LABELS` (`provideAuthLabels`) | No | The application's wording, once for the whole kit. |
50
+
51
+ ## Behaviour
52
+
53
+ - **Configuration.** `authConfig` is read once, when the page opens. A failed read only hides
54
+ the registration link, and is not taken for "no passkeys on this server": signing in never
55
+ depends on it.
56
+ - **Password step.** Only a 401 says "Incorrect username or password"; a 429 says to wait; any
57
+ other failure (a 5xx, a network error, an answer with neither `token` nor `mfaToken`) says the
58
+ sign-in failed. The password is dropped from memory as soon as the server accepted it.
59
+ - **Challenge.** One primary button per view: "Use a passkey" when it is offered, else "Verify".
60
+ A user with both factors gets the passkey first and the code form under "or". Spaces are
61
+ stripped from a code. A refused code empties the field; a 429 keeps it. A passkey-only user
62
+ whose passkey cannot run here (no WebAuthn in the browser, or passkeys off on the server) is
63
+ told why and given the backup-code form, never a dead end.
64
+ - **Passkey.** `startPasskeyChallenge`, the browser's prompt, then `finishPasskeyChallenge`. A
65
+ dismissed prompt is a quiet "Operation cancelled" (not an error) and keeps the screen. While
66
+ the prompt is open "Use a backup code" and "Back" stay usable; leaving drops the ceremony, so a
67
+ late answer is never sent.
68
+ - **Expiry.** A dead `mfaToken` (401 `invalid or expired token`, at the challenge, the passkey
69
+ or the enrolment) goes back to the credentials with "Your sign-in has expired, sign in again."
70
+ and the username kept.
71
+ - **Enrolment.** The page embeds `gbt-mfa-enrollment`: `completed` hands the session to
72
+ `AuthPort.setToken` then emits `loggedIn`; `cancelled` ("Back") returns to the credentials;
73
+ `expired` returns with the expiry message. The passkey option is only offered when the
74
+ server said `passkeysAvailable: true` and the browser has WebAuthn.
75
+ - **Focus.** On open the username field; after a failed sign-in the password field; on the
76
+ challenge the passkey button or the code field; after a failure the field (or button) to retry;
77
+ after "Back" the password field.
78
+
79
+ Failures are classified by status and by the body's `error` string (see
80
+ `AUTH_PORT_ERROR_BODIES`): the backend's own text is never shown.
81
+
82
+ ## Example
83
+
84
+ ```ts
85
+ // app.config.ts
86
+ providers: [
87
+ { provide: AUTH_PORT, useClass: HttpAuthPort }, // your adapter over HttpClient
88
+ {
89
+ provide: TOTP_QR_RENDERER,
90
+ useValue: (text, options) => import('qrcode').then((m) => m.toDataURL(text, options)),
91
+ },
92
+ provideAuthLabels({ login: { heading: 'Connexion', submit: 'Se connecter' /* … */ } }),
93
+ ]
94
+ ```
95
+
96
+ ```ts
97
+ @Component({
98
+ imports: [AuthLogin, Button, AuthFooterLink, RouterLink],
99
+ template: `
100
+ <gbt-auth-login (loggedIn)="router.navigateByUrl('/home')">
101
+ <img auth-logo src="/logo.svg" alt="Acme" width="160" height="40" />
102
+ <a gbtButton variant="link" gbtAuthFooterLink routerLink="/register">Create an account</a>
103
+ </gbt-auth-login>
104
+ `,
105
+ })
106
+ export class LoginPage {
107
+ protected readonly router = inject(Router)
108
+ }
109
+ ```
110
+
111
+ ## Accessibility
112
+
113
+ See [AUDIT.md](AUDIT.md). The page title (`<title>`) is the application's: set it on the route.