@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.
- package/README.md +231 -144
- package/accordion/README.md +56 -0
- package/alert/README.md +87 -0
- package/app-shell/README.md +133 -0
- package/auth/README.md +155 -0
- package/auth-activate/README.md +119 -0
- package/auth-login/README.md +113 -0
- package/auth-register/README.md +104 -0
- package/auth-reset-password/README.md +120 -0
- package/autocomplete/README.md +77 -0
- package/avatar/README.md +34 -0
- package/avatar-group/README.md +47 -0
- package/badge/README.md +177 -0
- package/bar-chart/README.md +44 -0
- package/breadcrumb/README.md +38 -0
- package/button/README.md +175 -0
- package/card/README.md +179 -0
- package/checkbox/README.md +50 -0
- package/checkbox-group/README.md +78 -0
- package/confirm-danger-modal/README.md +77 -0
- package/copy-button/README.md +90 -0
- package/copy-field/README.md +54 -0
- package/date-picker/README.md +84 -0
- package/description-list/README.md +63 -0
- package/dimension-card/README.md +39 -0
- package/disclosure/README.md +48 -0
- package/divider/README.md +31 -0
- package/drawer/README.md +49 -0
- package/empty-state/README.md +84 -0
- package/fesm2022/masmarino-gabarit-accordion.mjs +243 -0
- package/fesm2022/masmarino-gabarit-accordion.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-alert.mjs +208 -0
- package/fesm2022/masmarino-gabarit-alert.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-app-shell.mjs +378 -0
- package/fesm2022/masmarino-gabarit-app-shell.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-auth-activate.mjs +415 -0
- package/fesm2022/masmarino-gabarit-auth-activate.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-auth-login.mjs +467 -0
- package/fesm2022/masmarino-gabarit-auth-login.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-auth-register.mjs +457 -0
- package/fesm2022/masmarino-gabarit-auth-register.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-auth-reset-password.mjs +364 -0
- package/fesm2022/masmarino-gabarit-auth-reset-password.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-auth.mjs +844 -0
- package/fesm2022/masmarino-gabarit-auth.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-autocomplete.mjs +477 -0
- package/fesm2022/masmarino-gabarit-autocomplete.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-avatar-group.mjs +199 -0
- package/fesm2022/masmarino-gabarit-avatar-group.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-avatar.mjs +107 -0
- package/fesm2022/masmarino-gabarit-avatar.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-badge.mjs +449 -0
- package/fesm2022/masmarino-gabarit-badge.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-bar-chart.mjs +408 -0
- package/fesm2022/masmarino-gabarit-bar-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-breadcrumb.mjs +59 -0
- package/fesm2022/masmarino-gabarit-breadcrumb.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-button.mjs +374 -0
- package/fesm2022/masmarino-gabarit-button.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-card.mjs +400 -0
- package/fesm2022/masmarino-gabarit-card.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-chart.mjs +1289 -0
- package/fesm2022/masmarino-gabarit-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-checkbox-group.mjs +335 -0
- package/fesm2022/masmarino-gabarit-checkbox-group.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-checkbox.mjs +170 -0
- package/fesm2022/masmarino-gabarit-checkbox.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-confirm-danger-modal.mjs +387 -0
- package/fesm2022/masmarino-gabarit-confirm-danger-modal.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-copy-button.mjs +407 -0
- package/fesm2022/masmarino-gabarit-copy-button.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-copy-field.mjs +229 -0
- package/fesm2022/masmarino-gabarit-copy-field.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-date-picker.mjs +1238 -0
- package/fesm2022/masmarino-gabarit-date-picker.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-description-list.mjs +127 -0
- package/fesm2022/masmarino-gabarit-description-list.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-dimension-card.mjs +162 -0
- package/fesm2022/masmarino-gabarit-dimension-card.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-disclosure.mjs +154 -0
- package/fesm2022/masmarino-gabarit-disclosure.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-divider.mjs +90 -0
- package/fesm2022/masmarino-gabarit-divider.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-docs.mjs +21 -11
- package/fesm2022/masmarino-gabarit-docs.mjs.map +1 -1
- package/fesm2022/masmarino-gabarit-drawer.mjs +209 -0
- package/fesm2022/masmarino-gabarit-drawer.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-empty-state.mjs +226 -0
- package/fesm2022/masmarino-gabarit-empty-state.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-file-upload.mjs +335 -0
- package/fesm2022/masmarino-gabarit-file-upload.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-floating-panel.mjs +13 -0
- package/fesm2022/masmarino-gabarit-floating-panel.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-format.mjs +345 -0
- package/fesm2022/masmarino-gabarit-format.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-funnel-chart.mjs +247 -0
- package/fesm2022/masmarino-gabarit-funnel-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-gauge-bar.mjs +180 -0
- package/fesm2022/masmarino-gabarit-gauge-bar.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-git-field.mjs +127 -0
- package/fesm2022/masmarino-gabarit-git-field.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-icon-marker.mjs +150 -0
- package/fesm2022/masmarino-gabarit-icon-marker.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-icon.mjs +308 -0
- package/fesm2022/masmarino-gabarit-icon.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-input.mjs +493 -0
- package/fesm2022/masmarino-gabarit-input.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-job-graph.mjs +216 -0
- package/fesm2022/masmarino-gabarit-job-graph.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-job-status.mjs +104 -0
- package/fesm2022/masmarino-gabarit-job-status.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-line-chart.mjs +574 -0
- package/fesm2022/masmarino-gabarit-line-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-list-card.mjs +320 -0
- package/fesm2022/masmarino-gabarit-list-card.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-list-row.mjs +58 -0
- package/fesm2022/masmarino-gabarit-list-row.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-list-toolbar.mjs +369 -0
- package/fesm2022/masmarino-gabarit-list-toolbar.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-menu.mjs +461 -0
- package/fesm2022/masmarino-gabarit-menu.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-mfa-enrollment.mjs +897 -0
- package/fesm2022/masmarino-gabarit-mfa-enrollment.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-mfa-settings.mjs +629 -0
- package/fesm2022/masmarino-gabarit-mfa-settings.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-modal.mjs +260 -0
- package/fesm2022/masmarino-gabarit-modal.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-nav-tabs.mjs +332 -0
- package/fesm2022/masmarino-gabarit-nav-tabs.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-notification-dot.mjs +119 -0
- package/fesm2022/masmarino-gabarit-notification-dot.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-page-header.mjs +78 -0
- package/fesm2022/masmarino-gabarit-page-header.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-page-layout.mjs +157 -0
- package/fesm2022/masmarino-gabarit-page-layout.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-pagination.mjs +415 -0
- package/fesm2022/masmarino-gabarit-pagination.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-panel.mjs +80 -0
- package/fesm2022/masmarino-gabarit-panel.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-passkey-settings.mjs +606 -0
- package/fesm2022/masmarino-gabarit-passkey-settings.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-pie-chart.mjs +317 -0
- package/fesm2022/masmarino-gabarit-pie-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-popover.mjs +139 -0
- package/fesm2022/masmarino-gabarit-popover.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-radio-group.mjs +202 -0
- package/fesm2022/masmarino-gabarit-radio-group.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-save-status.mjs +142 -0
- package/fesm2022/masmarino-gabarit-save-status.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-search-bar.mjs +576 -0
- package/fesm2022/masmarino-gabarit-search-bar.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-secret-reveal.mjs +348 -0
- package/fesm2022/masmarino-gabarit-secret-reveal.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-segmented-control.mjs +272 -0
- package/fesm2022/masmarino-gabarit-segmented-control.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-select.mjs +510 -0
- package/fesm2022/masmarino-gabarit-select.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-skeleton-list.mjs +189 -0
- package/fesm2022/masmarino-gabarit-skeleton-list.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-skeleton.mjs +109 -0
- package/fesm2022/masmarino-gabarit-skeleton.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-slider.mjs +239 -0
- package/fesm2022/masmarino-gabarit-slider.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-sparkline.mjs +276 -0
- package/fesm2022/masmarino-gabarit-sparkline.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-spinner.mjs +86 -0
- package/fesm2022/masmarino-gabarit-spinner.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-stat-grid.mjs +139 -0
- package/fesm2022/masmarino-gabarit-stat-grid.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-stat-tile.mjs +312 -0
- package/fesm2022/masmarino-gabarit-stat-tile.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-stepper.mjs +219 -0
- package/fesm2022/masmarino-gabarit-stepper.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-switch.mjs +151 -0
- package/fesm2022/masmarino-gabarit-switch.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-table.mjs +206 -0
- package/fesm2022/masmarino-gabarit-table.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-tabs.mjs +210 -0
- package/fesm2022/masmarino-gabarit-tabs.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-tag-input.mjs +288 -0
- package/fesm2022/masmarino-gabarit-tag-input.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-tag.mjs +155 -0
- package/fesm2022/masmarino-gabarit-tag.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-textarea.mjs +369 -0
- package/fesm2022/masmarino-gabarit-textarea.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-timeline-chart.mjs +521 -0
- package/fesm2022/masmarino-gabarit-timeline-chart.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-toaster.mjs +220 -0
- package/fesm2022/masmarino-gabarit-toaster.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-tooltip.mjs +182 -0
- package/fesm2022/masmarino-gabarit-tooltip.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-tree.mjs +258 -0
- package/fesm2022/masmarino-gabarit-tree.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-user-chip.mjs +106 -0
- package/fesm2022/masmarino-gabarit-user-chip.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit.mjs +83 -24785
- package/fesm2022/masmarino-gabarit.mjs.map +1 -1
- package/file-upload/README.md +47 -0
- package/fonts/OFL-ibm-plex.txt +93 -0
- package/fonts/ibm-plex-mono-400.woff2 +0 -0
- package/fonts/ibm-plex-mono-500.woff2 +0 -0
- package/fonts/ibm-plex-sans-400.woff2 +0 -0
- package/fonts/ibm-plex-sans-500.woff2 +0 -0
- package/fonts/ibm-plex-sans-600.woff2 +0 -0
- package/fonts/ibm-plex-sans-condensed-600.woff2 +0 -0
- package/fonts/index.scss +28 -0
- package/funnel-chart/README.md +39 -0
- package/gauge-bar/README.md +35 -0
- package/git-field/README.md +34 -0
- package/icon/README.md +52 -0
- package/icon-marker/README.md +37 -0
- package/input/README.md +120 -0
- package/job-graph/README.md +76 -0
- package/job-status/README.md +34 -0
- package/line-chart/README.md +52 -0
- package/list-card/README.md +144 -0
- package/list-row/README.md +72 -0
- package/list-toolbar/README.md +52 -0
- package/menu/README.md +90 -0
- package/mfa-enrollment/README.md +189 -0
- package/mfa-settings/README.md +154 -0
- package/modal/README.md +72 -0
- package/nav-tabs/README.md +106 -0
- package/notification-dot/README.md +43 -0
- package/package.json +335 -1
- package/page-header/README.md +56 -0
- package/page-layout/README.md +76 -0
- package/pagination/README.md +73 -0
- package/panel/README.md +56 -0
- package/passkey-settings/README.md +120 -0
- package/pie-chart/README.md +85 -0
- package/popover/README.md +62 -0
- package/radio-group/README.md +47 -0
- package/save-status/README.md +44 -0
- package/search-bar/README.md +84 -0
- package/secret-reveal/README.md +60 -0
- package/segmented-control/README.md +79 -0
- package/select/README.md +61 -0
- package/skeleton/README.md +49 -0
- package/skeleton-list/README.md +40 -0
- package/slider/README.md +44 -0
- package/sparkline/README.md +37 -0
- package/spinner/README.md +41 -0
- package/src/lib/tokens/_a11y.scss +22 -0
- package/src/lib/tokens/_base.scss +31 -0
- package/src/lib/tokens/_palette.scss +52 -51
- package/src/lib/tokens/_semantic.scss +17 -124
- package/src/lib/tokens/_themes.scss +144 -0
- package/src/lib/tokens/_utilities.scss +10 -10
- package/src/lib/tokens/index.scss +3 -0
- package/stat-grid/README.md +47 -0
- package/stat-tile/README.md +75 -0
- package/stepper/README.md +67 -0
- package/switch/README.md +51 -0
- package/table/README.md +75 -0
- package/tabs/README.md +34 -0
- package/tag/README.md +34 -0
- package/tag-input/README.md +45 -0
- package/textarea/README.md +76 -0
- package/timeline-chart/README.md +49 -0
- package/toaster/README.md +92 -0
- package/tooltip/README.md +50 -0
- package/tree/README.md +79 -0
- package/types/masmarino-gabarit-accordion.d.ts +54 -0
- package/types/masmarino-gabarit-alert.d.ts +65 -0
- package/types/masmarino-gabarit-app-shell.d.ts +102 -0
- package/types/masmarino-gabarit-auth-activate.d.ts +70 -0
- package/types/masmarino-gabarit-auth-login.d.ts +63 -0
- package/types/masmarino-gabarit-auth-register.d.ts +66 -0
- package/types/masmarino-gabarit-auth-reset-password.d.ts +53 -0
- package/types/masmarino-gabarit-auth.d.ts +543 -0
- package/types/masmarino-gabarit-autocomplete.d.ts +139 -0
- package/types/masmarino-gabarit-avatar-group.d.ts +59 -0
- package/types/masmarino-gabarit-avatar.d.ts +31 -0
- package/types/masmarino-gabarit-badge.d.ts +139 -0
- package/types/masmarino-gabarit-bar-chart.d.ts +111 -0
- package/types/masmarino-gabarit-breadcrumb.d.ts +12 -0
- package/types/masmarino-gabarit-button.d.ts +108 -0
- package/types/masmarino-gabarit-card.d.ts +102 -0
- package/types/masmarino-gabarit-chart.d.ts +361 -0
- package/types/masmarino-gabarit-checkbox-group.d.ts +113 -0
- package/types/masmarino-gabarit-checkbox.d.ts +49 -0
- package/types/masmarino-gabarit-confirm-danger-modal.d.ts +94 -0
- package/types/masmarino-gabarit-copy-button.d.ts +111 -0
- package/types/masmarino-gabarit-copy-field.d.ts +64 -0
- package/types/masmarino-gabarit-date-picker.d.ts +397 -0
- package/types/masmarino-gabarit-description-list.d.ts +40 -0
- package/types/masmarino-gabarit-dimension-card.d.ts +55 -0
- package/types/masmarino-gabarit-disclosure.d.ts +44 -0
- package/types/masmarino-gabarit-divider.d.ts +20 -0
- package/types/masmarino-gabarit-docs.d.ts +20 -59
- package/types/masmarino-gabarit-drawer.d.ts +51 -0
- package/types/masmarino-gabarit-empty-state.d.ts +67 -0
- package/types/masmarino-gabarit-file-upload.d.ts +95 -0
- package/types/masmarino-gabarit-floating-panel.d.ts +7 -0
- package/types/masmarino-gabarit-format.d.ts +54 -0
- package/types/masmarino-gabarit-funnel-chart.d.ts +78 -0
- package/types/masmarino-gabarit-gauge-bar.d.ts +54 -0
- package/types/masmarino-gabarit-git-field.d.ts +39 -0
- package/types/masmarino-gabarit-icon-marker.d.ts +47 -0
- package/types/masmarino-gabarit-icon.d.ts +23 -0
- package/types/masmarino-gabarit-input.d.ts +181 -0
- package/types/masmarino-gabarit-job-graph.d.ts +63 -0
- package/types/masmarino-gabarit-job-status.d.ts +20 -0
- package/types/masmarino-gabarit-line-chart.d.ts +153 -0
- package/types/masmarino-gabarit-list-card.d.ts +87 -0
- package/types/masmarino-gabarit-list-row.d.ts +14 -0
- package/types/masmarino-gabarit-list-toolbar.d.ts +100 -0
- package/types/masmarino-gabarit-menu.d.ts +92 -0
- package/types/masmarino-gabarit-mfa-enrollment.d.ts +142 -0
- package/types/masmarino-gabarit-mfa-settings.d.ts +89 -0
- package/types/masmarino-gabarit-modal.d.ts +60 -0
- package/types/masmarino-gabarit-nav-tabs.d.ts +65 -0
- package/types/masmarino-gabarit-notification-dot.d.ts +34 -0
- package/types/masmarino-gabarit-page-header.d.ts +20 -0
- package/types/masmarino-gabarit-page-layout.d.ts +46 -0
- package/types/masmarino-gabarit-pagination.d.ts +109 -0
- package/types/masmarino-gabarit-panel.d.ts +21 -0
- package/types/masmarino-gabarit-passkey-settings.d.ts +94 -0
- package/types/masmarino-gabarit-pie-chart.d.ts +94 -0
- package/types/masmarino-gabarit-popover.d.ts +32 -0
- package/types/masmarino-gabarit-radio-group.d.ts +66 -0
- package/types/masmarino-gabarit-save-status.d.ts +39 -0
- package/types/masmarino-gabarit-search-bar.d.ts +183 -0
- package/types/masmarino-gabarit-secret-reveal.d.ts +95 -0
- package/types/masmarino-gabarit-segmented-control.d.ts +76 -0
- package/types/masmarino-gabarit-select.d.ts +145 -0
- package/types/masmarino-gabarit-skeleton-list.d.ts +54 -0
- package/types/masmarino-gabarit-skeleton.d.ts +26 -0
- package/types/masmarino-gabarit-slider.d.ts +73 -0
- package/types/masmarino-gabarit-sparkline.d.ts +70 -0
- package/types/masmarino-gabarit-spinner.d.ts +20 -0
- package/types/masmarino-gabarit-stat-grid.d.ts +39 -0
- package/types/masmarino-gabarit-stat-tile.d.ts +79 -0
- package/types/masmarino-gabarit-stepper.d.ts +67 -0
- package/types/masmarino-gabarit-switch.d.ts +42 -0
- package/types/masmarino-gabarit-table.d.ts +60 -0
- package/types/masmarino-gabarit-tabs.d.ts +40 -0
- package/types/masmarino-gabarit-tag-input.d.ts +78 -0
- package/types/masmarino-gabarit-tag.d.ts +35 -0
- package/types/masmarino-gabarit-textarea.d.ts +109 -0
- package/types/masmarino-gabarit-timeline-chart.d.ts +145 -0
- package/types/masmarino-gabarit-toaster.d.ts +62 -0
- package/types/masmarino-gabarit-tooltip.d.ts +38 -0
- package/types/masmarino-gabarit-tree.d.ts +71 -0
- package/types/masmarino-gabarit-user-chip.d.ts +26 -0
- package/types/masmarino-gabarit.d.ts +83 -6605
- package/user-chip/README.md +42 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# AuthRegister
|
|
2
|
+
|
|
3
|
+
The free registration page of the auth kit, outside the app shell, in the sign-in panel
|
|
4
|
+
([`gbt-auth-panel`](../auth/auth-panel/auth-panel.ts)). It asks the backend whether registration is open,
|
|
5
|
+
shows the form (or "Registration is closed"), creates the account, then takes the new account through
|
|
6
|
+
the mandatory first MFA enrolment ([`gbt-mfa-enrollment`](../mfa-enrollment/mfa-enrollment.ts)) right
|
|
7
|
+
in the panel. It never talks HTTP, never touches storage and never navigates: the backend is the
|
|
8
|
+
application's `AUTH_PORT`, and the page tells the application where to go through its outputs.
|
|
9
|
+
|
|
10
|
+
**Selector**: `gbt-auth-register`
|
|
11
|
+
|
|
12
|
+
## States
|
|
13
|
+
|
|
14
|
+
| State | What shows |
|
|
15
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
16
|
+
| loading | Until `AuthPort.authConfig()` answers: a skeleton of the form (`role="status"`, `aria-busy`, a visually hidden "Loading"), no heading, never a flash of the form. |
|
|
17
|
+
| open | The form: username, email address, password, one primary "Create my account", then the projected sign-in link. Also shown when `authConfig()` fails: the server enforces the switch anyway. |
|
|
18
|
+
| closed | `registrationEnabled` is false (or the server answered "registration is disabled" to a submit): a lock state with "Registration is closed", its explanation and one "Sign in" button. |
|
|
19
|
+
| enrolment | The server answered an `mfaToken`: the panel widens (`wide`), its heading becomes "Two-factor authentication" and `gbt-mfa-enrollment` replaces the form. A passkey is offered when `authConfig().passkeysAvailable` is true and the browser supports WebAuthn. |
|
|
20
|
+
| created | The enrolment was left ("Back") or its token expired: the account exists, so the page says "Your account has been created", names it (lower-cased, as stored; "The setup has expired." first when it expired) and offers one "Sign in" button. No session is held. |
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
| Input | Type | Default | Role |
|
|
25
|
+
| ------------------- | ------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| `labels` | `Partial<RegisterLabels>` | `{}` | Strings to change, over `provideAuthLabels({ register })` and the English defaults (`DEFAULT_REGISTER_LABELS`). |
|
|
27
|
+
| `minPasswordLength` | `number` | `MIN_PASSWORD_LENGTH` (8) | The server's minimum password length, checked before the round trip; also worded in the hint and the error. |
|
|
28
|
+
| `usernamePattern` | `RegExp` | `USERNAME_PATTERN` (a letter, 3 to 32) | The server's username rule, checked on the trimmed name before the round trip. Adjust the `usernameHint` and `usernameInvalid` labels with it. |
|
|
29
|
+
|
|
30
|
+
The enrolment's own strings are `MfaEnrollmentLabels`: localise them with `provideAuthLabels({ mfaEnrollment })`.
|
|
31
|
+
|
|
32
|
+
**A custom `usernamePattern` must not use the `g` or `y` regex flags (they make `.test()` stateful across
|
|
33
|
+
calls, so the same name would pass and fail in turn) and must mirror the server's own rule.** The same goes
|
|
34
|
+
for `minPasswordLength`: both only spare a round trip, the server stays the authority.
|
|
35
|
+
|
|
36
|
+
## Outputs
|
|
37
|
+
|
|
38
|
+
| Output | Payload | Role |
|
|
39
|
+
| ------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `registered` | `void` | The account exists and has a session: either the backend issued one at once (the port stored it), or the enrolment finished and the held-back session was handed to `AuthPort.setToken`. Navigate into the app. |
|
|
41
|
+
| `signIn` | `void` | "Sign in" was pressed in the closed or created state: go to the sign-in page. |
|
|
42
|
+
|
|
43
|
+
## Slots
|
|
44
|
+
|
|
45
|
+
| Selector | Role |
|
|
46
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| `[auth-logo]` | The application's logo (an `img`, `picture` or `svg`), on top of the panel. Optional. |
|
|
48
|
+
| `[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. |
|
|
49
|
+
| `[gbtAuthFooterLink]` | The link to the sign-in page, under the form after "Already have an account?". An `a gbtButton variant="link"` carrying `routerLink` or `href`. No footer when absent. |
|
|
50
|
+
|
|
51
|
+
## Behaviour
|
|
52
|
+
|
|
53
|
+
- **Checks before the request.** Nothing is said while the user types; after a first "Create my account"
|
|
54
|
+
every wrong field shows its rule (in place of its hint, as its only `aria-describedby`) and the focus moves
|
|
55
|
+
to the first wrong one. The checks then stay live. Nothing is sent while a field is wrong.
|
|
56
|
+
- **Sent**: `register(username.trim(), email.trim(), password)`. A second submit while in flight is ignored;
|
|
57
|
+
the button shows its spinner and is disabled. The password is emptied as soon as the server answered.
|
|
58
|
+
- **Failures** are worded from the labels, never from the backend's text, in an alert (`role="alert"`), and the
|
|
59
|
+
focus goes where the user retypes: a 400 naming a field focuses that field ("Check the fields"); a 400 naming
|
|
60
|
+
none focuses the alert; a reserved name, a taken name or address (409) focus the field concerned; a 429 says
|
|
61
|
+
to wait; anything else (5xx, network, a browser error) says the creation failed and keeps what was typed. A
|
|
62
|
+
400 "registration is disabled" switches to the closed state. The recognised bodies are in
|
|
63
|
+
`AUTH_PORT_ERROR_BODIES`.
|
|
64
|
+
- **Focus**: the form starts in the username field; the closed and created states move the focus to their
|
|
65
|
+
`h1` (focusable by script, not a tab stop) so the change is announced.
|
|
66
|
+
- **Sessions**: the page never stores one. A backend without MFA enforcement answers a `token` (the port stores
|
|
67
|
+
it): `registered` fires at once. Otherwise the enrolment keeps the session until the backup codes are
|
|
68
|
+
acknowledged, then the page hands it to `AuthPort.setToken` and emits `registered`.
|
|
69
|
+
|
|
70
|
+
## Example
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// app.config.ts
|
|
74
|
+
providers: [
|
|
75
|
+
{ provide: AUTH_PORT, useClass: HttpAuthPort }, // your adapter over HttpClient
|
|
76
|
+
{
|
|
77
|
+
provide: TOTP_QR_RENDERER,
|
|
78
|
+
useValue: (text, options) => import('qrcode').then((m) => m.toDataURL(text, options)),
|
|
79
|
+
},
|
|
80
|
+
provideAuthLabels({ register: { intro: 'Join Acme to host your repositories.' } }),
|
|
81
|
+
]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
@Component({
|
|
86
|
+
imports: [AuthRegister, Button, AuthFooterLink, RouterLink],
|
|
87
|
+
template: `
|
|
88
|
+
<gbt-auth-register
|
|
89
|
+
(registered)="router.navigateByUrl('/home')"
|
|
90
|
+
(signIn)="router.navigateByUrl('/login')"
|
|
91
|
+
>
|
|
92
|
+
<img auth-logo src="/logo.svg" alt="Acme" width="160" height="40" />
|
|
93
|
+
<a gbtButton variant="link" gbtAuthFooterLink routerLink="/login">Sign in</a>
|
|
94
|
+
</gbt-auth-register>
|
|
95
|
+
`,
|
|
96
|
+
})
|
|
97
|
+
export class RegisterRoute {
|
|
98
|
+
protected readonly router = inject(Router)
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Accessibility
|
|
103
|
+
|
|
104
|
+
See [AUDIT.md](AUDIT.md). The panel owns the page's `<main>` landmark and its `h1`.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# AuthResetPassword
|
|
2
|
+
|
|
3
|
+
The password-reset page of the auth kit: where the link of a password-reset mail lands, outside the app
|
|
4
|
+
shell, in the sign-in panel ([`gbt-auth-panel`](../auth/auth-panel/auth-panel.ts)). An administrator has
|
|
5
|
+
reset the password of an existing account; the user follows the link and chooses a new password. No
|
|
6
|
+
session comes out of it: they sign in afterwards, through their second factor as on any sign-in (a
|
|
7
|
+
password reset leaves the account's factors untouched). It never talks HTTP, never reads the URL and
|
|
8
|
+
never navigates: the backend is the application's `AUTH_PORT`, the token is an input, and the page tells
|
|
9
|
+
the application where to go through its outputs.
|
|
10
|
+
|
|
11
|
+
**Selector**: `gbt-auth-reset-password`
|
|
12
|
+
|
|
13
|
+
It is the sibling of [`gbt-auth-activate`](../auth-activate/README.md): same one-time link mechanics, same
|
|
14
|
+
form, same failure handling; only the call (`resetPassword` instead of `activate`), the output and the
|
|
15
|
+
wording differ.
|
|
16
|
+
|
|
17
|
+
## Views
|
|
18
|
+
|
|
19
|
+
| View | What shows |
|
|
20
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
+
| form | A token was given: "Choose a new password", why (an administrator reset it), New password (with its hint), Confirm the new password, one primary "Set new password", then the projected sign-in link. |
|
|
22
|
+
| success | The server accepted: "Your password has been changed", sign in with the new one, one "Sign in" button. |
|
|
23
|
+
| invalid | No token (`null` or `''`), or the server refused it (unknown, expired or used): an error-toned state, "This link does not work", ask an administrator for a new link, one "Sign in". |
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
| Input | Type | Default | Role |
|
|
28
|
+
| ------------------- | ------------------------------ | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| `token` | `string \| null` | `null` | The reset link's token, as the application read it from its URL with `activationToken(fragment, null)`. `null` (or `''`) is the dead link, without any request. A new value starts the page over. |
|
|
30
|
+
| `labels` | `Partial<ResetPasswordLabels>` | `{}` | Strings to change, over `provideAuthLabels({ resetPassword })` and the English defaults (`DEFAULT_RESET_PASSWORD_LABELS`). |
|
|
31
|
+
| `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. |
|
|
32
|
+
|
|
33
|
+
## Outputs
|
|
34
|
+
|
|
35
|
+
| Output | Payload | Role |
|
|
36
|
+
| --------------- | ------- | ------------------------------------------------------------------------------------ |
|
|
37
|
+
| `passwordReset` | `void` | The server accepted the new password: the success view shows. No session was opened. |
|
|
38
|
+
| `signIn` | `void` | "Sign in" was pressed in the success or dead-link view: go to the sign-in page. |
|
|
39
|
+
|
|
40
|
+
The success output is `passwordReset`, not `reset`: an output named after a native DOM event would
|
|
41
|
+
also catch the `reset` events bubbling from the page's own `<form>`.
|
|
42
|
+
|
|
43
|
+
## Slots
|
|
44
|
+
|
|
45
|
+
| Selector | Role |
|
|
46
|
+
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| `[auth-logo]` | The application's logo (an `img`, `picture` or `svg`), on top of the panel. Optional. |
|
|
48
|
+
| `[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. |
|
|
49
|
+
| `[gbtAuthFooterLink]` | The link to the sign-in page, under the form after "Already set your new password?". An `a gbtButton variant="link"` carrying `routerLink` or `href`. No footer when absent. |
|
|
50
|
+
|
|
51
|
+
## Behaviour
|
|
52
|
+
|
|
53
|
+
- **The token.** The page sends it with the new password (`resetPassword(token, password)`) and never
|
|
54
|
+
renders it (not in the markup, not in a field). Once spent (success) or refused (a 400 other than a weak
|
|
55
|
+
password), it is dropped: the page does not send it again until a new `token` arrives.
|
|
56
|
+
- **The application's part** (it owns the URL): put the token in the link's **fragment**
|
|
57
|
+
(`/reset-password#token=…`) so that no server, proxy or access log ever sees it; read it once with
|
|
58
|
+
`activationToken(route.snapshot.fragment, null)` (the helper is shared with the activation: a token not
|
|
59
|
+
shaped like the server's, 64 hexadecimal characters by default, is `null`; pass your own `shape` as its
|
|
60
|
+
third argument if your backend's differs); then remove it (and any other parameter) from the address bar
|
|
61
|
+
and the history entry, e.g. `router.navigateByUrl('/reset-password', { replaceUrl: true })` after the
|
|
62
|
+
first render, so it does not linger in a screenshot or a shared tab. Unlike the activation, there is no
|
|
63
|
+
older `?token=` link to support: read the fragment only.
|
|
64
|
+
- **The `token` input must be a one-time snapshot of the URL, never a value that reactively follows the
|
|
65
|
+
URL (e.g. a signal derived from `route.fragment`): the component resets when it changes.** Scrubbing the
|
|
66
|
+
URL as above would otherwise turn the token into `null` and flip the page to the dead-link view, even over
|
|
67
|
+
its success view. Read it into a plain field, as in the example below.
|
|
68
|
+
- **`minPasswordLength` must mirror the server's own rule.** It only spares a round trip: the server stays
|
|
69
|
+
the authority, and a looser value only moves the refusal to the server's answer.
|
|
70
|
+
- **Checks before the request.** Nothing is said while typing; after a first attempt the password rule and
|
|
71
|
+
the confirmation ("Confirm your new password", "The passwords do not match") show under their fields, the
|
|
72
|
+
focus moves to the first wrong one, and the checks stay live.
|
|
73
|
+
- **Failures** are worded from the labels, in an alert, the focus back in the password field: a weak-password
|
|
74
|
+
400 keeps the form (the link is still good), a 429 says to wait, anything else (5xx, network) says the new
|
|
75
|
+
password could not be set and the same token can be retried. Any other 400 is the dead link: the server
|
|
76
|
+
is expected to answer one generic 400 for an unknown, expired, used or malformed token, so that nobody
|
|
77
|
+
probing links can tell them apart; the page words them all the same way. The failures are read by
|
|
78
|
+
`classifyActivateFailure`, shared with the activation.
|
|
79
|
+
- **Focus**: the form starts in the new-password field; the success and dead-link views move the focus to
|
|
80
|
+
their `h1` (focusable by script, not a tab stop). The passwords are emptied when the server accepted or
|
|
81
|
+
refused the link.
|
|
82
|
+
|
|
83
|
+
## Example
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// app.config.ts
|
|
87
|
+
providers: [
|
|
88
|
+
{ provide: AUTH_PORT, useClass: HttpAuthPort }, // your adapter over HttpClient
|
|
89
|
+
provideAuthLabels({ resetPassword: { signInPrompt: 'Password already changed?' } }),
|
|
90
|
+
]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
@Component({
|
|
95
|
+
imports: [AuthResetPassword, Button, AuthFooterLink, RouterLink],
|
|
96
|
+
template: `
|
|
97
|
+
<gbt-auth-reset-password [token]="token" (signIn)="router.navigateByUrl('/login')">
|
|
98
|
+
<img auth-logo src="/logo.svg" alt="Acme" width="160" height="40" />
|
|
99
|
+
<a gbtButton variant="link" gbtAuthFooterLink routerLink="/login">Sign in</a>
|
|
100
|
+
</gbt-auth-reset-password>
|
|
101
|
+
`,
|
|
102
|
+
})
|
|
103
|
+
export class ResetPasswordRoute {
|
|
104
|
+
protected readonly router = inject(Router)
|
|
105
|
+
private readonly route = inject(ActivatedRoute)
|
|
106
|
+
// Read once, then scrubbed from the address bar and the history entry.
|
|
107
|
+
protected readonly token = activationToken(this.route.snapshot.fragment, null)
|
|
108
|
+
|
|
109
|
+
constructor() {
|
|
110
|
+
const { fragment, queryParamMap } = this.route.snapshot
|
|
111
|
+
if (fragment !== null || queryParamMap.keys.length > 0) {
|
|
112
|
+
afterNextRender(() => void this.router.navigateByUrl('/reset-password', { replaceUrl: true }))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Accessibility
|
|
119
|
+
|
|
120
|
+
See [AUDIT.md](AUDIT.md). The panel owns the page's `<main>` landmark and its `h1`.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Autocomplete
|
|
2
|
+
|
|
3
|
+
Text field with asynchronous suggestions. The app owns the data source
|
|
4
|
+
— it supplies a `search` function, `Autocomplete` owns debouncing the
|
|
5
|
+
input, tracking loading/empty/error state, and discarding a response
|
|
6
|
+
that arrives after a more recent one. Integrated with reactive forms
|
|
7
|
+
and `ngModel`, like `GbtInput`/`Select`.
|
|
8
|
+
|
|
9
|
+
Distinct from `Select` (a fixed, known-upfront list of options) and
|
|
10
|
+
from `SearchBar` (an organism dedicated exclusively to the header's
|
|
11
|
+
search — not a reusable form field).
|
|
12
|
+
|
|
13
|
+
**Selector**: `gbt-autocomplete`
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
| Input | Type | Default | Role |
|
|
18
|
+
| --------------------- | ------------------------------------------------ | --------------------- | ---------------------------------------------------------------------------------------------- |
|
|
19
|
+
| `id` | `string` | generated | DOM id, associates the `<label>`. |
|
|
20
|
+
| `label` | `string` | `''` | Visible label. |
|
|
21
|
+
| `search` | `(query: string) => Observable<T[]> \| Promise<T[]>` | required | Runs the search — `Autocomplete` never makes the HTTP call itself. |
|
|
22
|
+
| `displayFn` | `(item: T) => string` | `String(item)` | Formats an item as text, both in the input once selected and as the default option rendering. |
|
|
23
|
+
| `itemTemplate` | `TemplateRef<{ $implicit: T }>` | none | Custom rendering per suggestion (e.g. avatar + name), in place of the plain `displayFn` text. |
|
|
24
|
+
| `debounceMs` | `number` | `300` | Delay after the last keystroke before `search` runs. |
|
|
25
|
+
| `minLength` | `number` | `1` | Minimum query length (after trimming) before searching. |
|
|
26
|
+
| `placeholder` | `string` | `''` | Input placeholder. |
|
|
27
|
+
| `disabled` | `boolean` | `false` | Disables the field. |
|
|
28
|
+
| `required` | `boolean` | `false` | Native `required` attribute. |
|
|
29
|
+
| `errorMessage` | `string \| null` | `null` | Error message shown under the field (form validation — distinct from a failed search). |
|
|
30
|
+
| `loadingMessage` | `string` | `'Searching…'` | Shown in the panel and announced while `search` is pending. |
|
|
31
|
+
| `noResultsMessage` | `string` | `'No results'` | Shown when `search` resolves to an empty array. |
|
|
32
|
+
| `searchErrorMessage` | `string` | `'Search failed'` | Shown when `search` rejects or errors. |
|
|
33
|
+
| `resultsAnnouncement` | `(count: number) => string` | `` `${count} result(s)` `` | Text announced to screen readers once results land. |
|
|
34
|
+
|
|
35
|
+
## Outputs
|
|
36
|
+
|
|
37
|
+
| Output | Type | Role |
|
|
38
|
+
| -------------- | ---- | --------------------------------------------------------------------------------------- |
|
|
39
|
+
| `itemSelected` | `T` | Emitted when a suggestion is picked — in addition to the `ControlValueAccessor` value. |
|
|
40
|
+
|
|
41
|
+
## Behavior
|
|
42
|
+
|
|
43
|
+
- Debounced: `search` only runs `debounceMs` after the last keystroke, not once per keystroke.
|
|
44
|
+
- A response that resolves after a more recent one is discarded — typing "a" then "al" before the first search settles never lets the "a" results flash back over "al"'s.
|
|
45
|
+
- Editing the text away from the current selection clears the form value (`null`) immediately — a stale object never lingers behind edited text.
|
|
46
|
+
- Works with either a `Promise`-returning or an `Observable`-returning `search` (an active `Observable` subscription is replaced, not stacked, when a newer search starts).
|
|
47
|
+
- The panel is positioned with `getBoundingClientRect()`, the same technique as `Select` — it escapes an ancestor's `overflow: hidden`.
|
|
48
|
+
|
|
49
|
+
## Example
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<gbt-autocomplete
|
|
53
|
+
label="Utilisateur"
|
|
54
|
+
placeholder="Rechercher un utilisateur…"
|
|
55
|
+
[search]="searchUsers"
|
|
56
|
+
[displayFn]="displayUser"
|
|
57
|
+
formControlName="assignee"
|
|
58
|
+
/>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
searchUsers = (query: string) =>
|
|
63
|
+
this.http.get<User[]>('/api/users', { params: { q: query } })
|
|
64
|
+
|
|
65
|
+
displayUser = (user: User) => user.name
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Custom rendering per suggestion, via `itemTemplate`:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<gbt-autocomplete [search]="searchUsers" [displayFn]="displayUser" [itemTemplate]="userRow" formControlName="assignee">
|
|
72
|
+
</gbt-autocomplete>
|
|
73
|
+
<ng-template #userRow let-user>
|
|
74
|
+
<img [src]="user.avatarUrl" width="20" height="20" />
|
|
75
|
+
<span>{{ user.name }}</span>
|
|
76
|
+
</ng-template>
|
|
77
|
+
```
|
package/avatar/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
Visual representation of a user — an image, or a fallback of initials
|
|
4
|
+
computed from their name if there's no image, or the image fails to
|
|
5
|
+
load.
|
|
6
|
+
|
|
7
|
+
**Selector**: `gbt-avatar`
|
|
8
|
+
|
|
9
|
+
## Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Role |
|
|
12
|
+
| ------ | ----------------------- | ------- | --------------------------------------------------------------------- |
|
|
13
|
+
| `name` | `string` | required | Full name — drives the initials fallback and the image's `alt` text. |
|
|
14
|
+
| `src` | `string \| null` | `null` | Image URL. Falls back to initials if absent, or if it fails to load. |
|
|
15
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 24px / 32px / 48px. |
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<gbt-avatar name="Ada Lovelace" [src]="user.avatarUrl" size="sm" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Behavior
|
|
24
|
+
|
|
25
|
+
- Initials: first letter of the first and last word of `name` (e.g.
|
|
26
|
+
"Ada Lovelace" → "AL"), or the first two letters for a single-word
|
|
27
|
+
name.
|
|
28
|
+
- A failed image load (`(error)`) switches to the initials fallback —
|
|
29
|
+
the broken-image icon a browser would otherwise show is never
|
|
30
|
+
visible.
|
|
31
|
+
- The fallback uses a single neutral color (`--primary`/
|
|
32
|
+
`--text-on-primary`, already AAA-contrast), not a color hashed per
|
|
33
|
+
user — simpler, and one fewer palette to audit. Revisit if visually
|
|
34
|
+
distinguishing users in a dense list turns out to matter.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# AvatarGroup
|
|
2
|
+
|
|
3
|
+
A row of overlapping `Avatar`s — up to `max` shown, the rest folded
|
|
4
|
+
into a "+N" indicator that opens a menu listing them. Every avatar,
|
|
5
|
+
visible or in the overflow menu, is clickable — e.g. to filter a list
|
|
6
|
+
down to that one user.
|
|
7
|
+
|
|
8
|
+
**Selector**: `gbt-avatar-group`
|
|
9
|
+
|
|
10
|
+
## Inputs
|
|
11
|
+
|
|
12
|
+
| Input | Type | Default | Role |
|
|
13
|
+
| ----------- | -------------------------- | --------- | -------------------------------------------------------------------- |
|
|
14
|
+
| `items` | `T[]` (`{ name, src? }`) | required | The users to show. `T` can carry extra fields (e.g. `id`) — the full item comes back on `itemClick`. |
|
|
15
|
+
| `max` | `number` | `5` | Avatars shown before folding the rest into "+N". |
|
|
16
|
+
| `ariaLabel` | `string` | `'Users'` | Accessible name of the avatar row. |
|
|
17
|
+
| `moreLabel` | `(count: number) => string`| `` (count) => `${count} more` `` | Accessible name of the "+N" button, and the overflow menu's label. |
|
|
18
|
+
| `activeItem` | `T \| null` | `null` | The currently active filter, compared by reference against `items`. A visible avatar gets an outer ring; the matching row in the overflow menu gets a check icon (both also get `aria-current="true"`). |
|
|
19
|
+
|
|
20
|
+
## Outputs
|
|
21
|
+
|
|
22
|
+
| Output | Type | Role |
|
|
23
|
+
| ----------- | ---- | ----------------------------------------------------------------------- |
|
|
24
|
+
| `itemClick` | `T` | Emitted when any avatar is clicked — the visible ones, or one from the overflow menu. |
|
|
25
|
+
|
|
26
|
+
## Example
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<gbt-avatar-group
|
|
30
|
+
[items]="users"
|
|
31
|
+
[max]="5"
|
|
32
|
+
[activeItem]="selectedUser"
|
|
33
|
+
(itemClick)="selectedUser = selectedUser === $event ? null : $event"
|
|
34
|
+
/>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
users: User[] = [{ id: '1', name: 'Ada Lovelace', src: user.avatarUrl }, ...]
|
|
39
|
+
selectedUser: User | null = null
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Behavior
|
|
43
|
+
|
|
44
|
+
- Reuses `Avatar` for each item (`md` size in the row, `sm` size in the
|
|
45
|
+
overflow menu) — no separate initials/fallback logic of its own.
|
|
46
|
+
- The overflow menu is positioned the same way as `Select`/`Menu`
|
|
47
|
+
(`getBoundingClientRect`), closes on `Escape` or an outside click.
|
package/badge/README.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Badge
|
|
2
|
+
|
|
3
|
+
Short status/category label — a colored pill for text content (e.g. a
|
|
4
|
+
role, a status, a count), purely informational. Not interactive by default;
|
|
5
|
+
see [Copy](#copy) for the one exception (a small copy button inside the
|
|
6
|
+
pill). Not removable; see the component's GitHub issue if you need a
|
|
7
|
+
dismissible chip variant later.
|
|
8
|
+
|
|
9
|
+
**Selector**: `gbt-badge`. Also replaces the former `gbt-code-chip` (via the
|
|
10
|
+
`mono`/`copyable` inputs below) and `gbt-counter` (via `value`) — see
|
|
11
|
+
[Migrating from CodeChip](#migrating-from-codechip) and
|
|
12
|
+
[Migrating from Counter](#migrating-from-counter).
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
| Input | Type | Default | Role |
|
|
17
|
+
| ------------- | ----------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `variant` | `BadgeVariant` | `'neutral'` | `'neutral' \| 'success' \| 'warning' \| 'error' \| 'info'`. |
|
|
19
|
+
| `icon` | `string` | none | Optional `gbt-icon` name, shown before the label. |
|
|
20
|
+
| `appearance` | `'filled' \| 'outline'` | `'filled'` | `outline`: transparent, 1px border in the variant's text colour (`--border-color` for `neutral`). Same height as `filled`. |
|
|
21
|
+
| `size` | `'md' \| 'sm'` | `'md'` | `sm`: smaller pill (11px), for counters and dense rows. |
|
|
22
|
+
| `truncate` | `boolean` | `false` | The badge may shrink below its content and ellipsises its label (see below). |
|
|
23
|
+
| `tabularNums` | `boolean` | `false` | `font-variant-numeric: tabular-nums`, so a live count keeps a steady width. |
|
|
24
|
+
| `mono` | `boolean` | `false` | Monospace font, hairline border, tighter shape — the look of the former `gbt-code-chip`. See [below](#mono-monospacecode). |
|
|
25
|
+
| `maxWidth` | `string \| null` | `null` | Caps the pill's width (any CSS length, `12rem`). From `gbt-code-chip`. |
|
|
26
|
+
| `fullText` | `string \| null` | `null` | The complete text, as a native tooltip (`title`) on the label: useful when `truncate` cuts it. From `gbt-code-chip`. |
|
|
27
|
+
| `copyable` | `boolean` | `false` | Adds a small copy button inside the badge. From `gbt-code-chip`. |
|
|
28
|
+
| `copyValue` | `string \| null` | `null` | What the button copies; by default the badge's own visible text. |
|
|
29
|
+
| `copyLabel` | `string` | `'Copy'` | Accessible name of the copy button ("Copy the commit SHA"). |
|
|
30
|
+
| `copiedText` | `string` | `'Copied'` | Announced after a copy (visually hidden live region: the glyph turns into a check). |
|
|
31
|
+
| `failedText` | `string` | `'Copy failed'` | Announced when the copy is refused; the badge text is selected for a manual copy. |
|
|
32
|
+
| `feedbackMs` | `number` | `2000` | How long the copied glyph stays. |
|
|
33
|
+
| `value` | `number \| null` | `null` | Numeric counter mode: replaces the projected content with this count. From `gbt-counter`. See [below](#value-numeric-counter-mode). |
|
|
34
|
+
| `max` | `number \| null` | `null` | Counter mode: caps the display, e.g. `max` `99` shows `120` as `99+`. `null`: no cap. |
|
|
35
|
+
| `hideZero` | `boolean` | `false` | Counter mode: hides the badge (`hidden` on the host) when the shown count is `0`. |
|
|
36
|
+
| `label` | `string \| null` | `null` | Counter mode: visually hidden text read after the number ("12 open issues"). |
|
|
37
|
+
|
|
38
|
+
## Outputs
|
|
39
|
+
|
|
40
|
+
| Output | Type | Role |
|
|
41
|
+
| ------------ | -------- | ----------------------------------------------------------------------- |
|
|
42
|
+
| `copied` | `string` | Emitted with the copied text after a successful copy (`copyable` only). |
|
|
43
|
+
| `copyFailed` | `void` | Emitted when the copy is refused (`copyable` only). |
|
|
44
|
+
|
|
45
|
+
## Content
|
|
46
|
+
|
|
47
|
+
The badge's text comes from projected content (`<ng-content />`), not
|
|
48
|
+
an input — like a native `<span>`, so it composes naturally with
|
|
49
|
+
interpolation, `@if`, or plain text — **except** in `value` mode (see
|
|
50
|
+
below), where the projected content is ignored and the computed count is
|
|
51
|
+
rendered instead.
|
|
52
|
+
|
|
53
|
+
## Truncation
|
|
54
|
+
|
|
55
|
+
In a narrow row a long label pushes its badge past the container. With `truncate`
|
|
56
|
+
the host and the pill are allowed to shrink (`min-width: 0`, `max-width: 100%`) and
|
|
57
|
+
the label ends in an ellipsis; a `max-width` on `<gbt-badge>` (or the `maxWidth` input)
|
|
58
|
+
caps it below the container width. The full text stays in the DOM for assistive
|
|
59
|
+
technology; add a `title` on the host, or the `fullText` input, for a hover tooltip.
|
|
60
|
+
If the badge is a flex item, give its wrapper `min-width: 0` as well.
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<li style="display: flex; min-width: 0">
|
|
64
|
+
<gbt-badge appearance="outline" truncate [attr.title]="event">{{ event }}</gbt-badge>
|
|
65
|
+
</li>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## `mono` (monospace/code)
|
|
69
|
+
|
|
70
|
+
`mono` gives the badge the monospace font, hairline border and tighter shape
|
|
71
|
+
suited for a commit SHA, a tag, a branch name or a repository path, in a row,
|
|
72
|
+
a meta line or a sentence. It
|
|
73
|
+
layers on top of `variant`/`appearance`: an explicit colored variant still
|
|
74
|
+
wins for background/color (declared later in `badge.scss`); `mono` alone
|
|
75
|
+
only changes the shape and the type.
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<gbt-badge mono icon="git-commit" fullText="{{ sha }}">{{ sha.slice(0, 7) }}</gbt-badge>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Copy
|
|
82
|
+
|
|
83
|
+
Same engine as [`gbt-copy-button`](../copy-button/README.md) (Clipboard API, `execCommand` fallback,
|
|
84
|
+
refusal selects the text), reusing `ClipboardFeedback` — no logic is duplicated. The badge itself is
|
|
85
|
+
not interactive: only its copy button is, with a 24 px hit area (drawn outside the pill so it does not
|
|
86
|
+
grow). The outcome is announced by a `role="status"` region that exists as long as the badge is
|
|
87
|
+
`copyable`.
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<gbt-badge mono icon="git-commit" copyable [copyValue]="commit.sha" copyLabel="Copy the commit SHA"
|
|
91
|
+
>{{ commit.sha.slice(0, 7) }}</gbt-badge
|
|
92
|
+
>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## `value` (numeric counter mode)
|
|
96
|
+
|
|
97
|
+
Setting `value` switches the badge into the former `gbt-counter`'s mode: the
|
|
98
|
+
projected content is **ignored**, and the badge computes and renders the
|
|
99
|
+
count itself — fractions cut, negatives and non-numbers count as `0` — capped
|
|
100
|
+
by `max` (`120` with `max` `99` shows `99+`) and hideable at `0` with
|
|
101
|
+
`hideZero` (via the `hidden` attribute — the element stays in the DOM, no
|
|
102
|
+
`@if` needed around it). `label` adds a visually hidden suffix after the
|
|
103
|
+
number ("12 open issues"): **a bare number is ambiguous for assistive
|
|
104
|
+
technology** unless the surrounding context (a heading, a tab) already says
|
|
105
|
+
what it counts — see [AUDIT.md](AUDIT.md).
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<h2>Pages <gbt-badge [value]="pages().length" hideZero label="pages" /></h2>
|
|
109
|
+
|
|
110
|
+
<button gbtTab>Closed <gbt-badge [value]="closed()" [max]="99" size="sm" /></button>
|
|
111
|
+
<gbt-badge [value]="toReview()" variant="info" size="sm" label="to review" />
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Badge already has `tabularNums` for equal-width digits (a live count does not
|
|
115
|
+
jitter) — set it explicitly in counter usage: it is not implied by `value`.
|
|
116
|
+
|
|
117
|
+
## Migrating from CodeChip
|
|
118
|
+
|
|
119
|
+
`gbt-code-chip` is gone; use `gbt-badge` with `mono` (its label is a `<span>`, not a `<code>`
|
|
120
|
+
wrapper, styled the same way). Every other `gbt-code-chip` input keeps its name:
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<!-- before -->
|
|
124
|
+
<gbt-code-chip icon="git-commit" copyable [copyValue]="sha" copyLabel="Copy the commit SHA"
|
|
125
|
+
>{{ sha.slice(0, 7) }}</gbt-code-chip
|
|
126
|
+
>
|
|
127
|
+
|
|
128
|
+
<!-- after -->
|
|
129
|
+
<gbt-badge mono icon="git-commit" copyable [copyValue]="sha" copyLabel="Copy the commit SHA"
|
|
130
|
+
>{{ sha.slice(0, 7) }}</gbt-badge
|
|
131
|
+
>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
One behavioural difference: `gbt-code-chip`'s `truncate` defaulted to `true`
|
|
135
|
+
(and `truncate="false"` made it wrap instead of overflowing, via
|
|
136
|
+
`white-space: normal; overflow-wrap: anywhere`). `gbt-badge`'s `truncate`
|
|
137
|
+
keeps its own default of `false` and has no such wrapping mode — a mono
|
|
138
|
+
badge that needs the ellipsis behaviour should set `truncate` explicitly; one
|
|
139
|
+
that needs to wrap instead should sit inside a block-level container.
|
|
140
|
+
|
|
141
|
+
## Migrating from Counter
|
|
142
|
+
|
|
143
|
+
`gbt-counter` is gone; use `gbt-badge` with `value` (and the same `max` /
|
|
144
|
+
`hideZero` / `label` names):
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<!-- before -->
|
|
148
|
+
<gbt-counter [value]="pages().length" hideZero label="pages" />
|
|
149
|
+
|
|
150
|
+
<!-- after -->
|
|
151
|
+
<gbt-badge [value]="pages().length" hideZero label="pages" />
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`gbt-counter`'s `appearance` (`'neutral' | 'primary'`) has no exact `gbt-badge`
|
|
155
|
+
equivalent: Badge's own `variant`/`appearance`/`size` axes replace it.
|
|
156
|
+
`appearance="neutral"` (the old default) is closest to `gbt-badge`'s own
|
|
157
|
+
default look (no `variant`, `appearance="filled"`); there is no ready-made
|
|
158
|
+
"brand-filled" look for the old `appearance="primary"` — pick the semantic
|
|
159
|
+
`variant` that fits (e.g. `variant="info"`) or a custom class. `size="sm"`/
|
|
160
|
+
`"md"` map directly. This is a visual difference to review when migrating a
|
|
161
|
+
call site, not just a rename.
|
|
162
|
+
|
|
163
|
+
## Example
|
|
164
|
+
|
|
165
|
+
```html
|
|
166
|
+
<gbt-badge variant="success">Actif</gbt-badge>
|
|
167
|
+
<gbt-badge variant="error" icon="alert-triangle">Erreur</gbt-badge>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<gbt-badge appearance="outline" variant="success">Current version</gbt-badge>
|
|
172
|
+
<gbt-badge size="sm" tabularNums>1,118</gbt-badge>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Accessibility
|
|
176
|
+
|
|
177
|
+
See [AUDIT.md](AUDIT.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# BarChart
|
|
2
|
+
|
|
3
|
+
Bar chart on the dataviz base — measures its container, reacts to the
|
|
4
|
+
pointer and keyboard, carries its own visually-hidden
|
|
5
|
+
`gbt-chart-table`.
|
|
6
|
+
|
|
7
|
+
**Selector**: `gbt-bar-chart`
|
|
8
|
+
|
|
9
|
+
## Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Role |
|
|
12
|
+
| -------------- | ------------------------------------------- | -------- | ---------------------------------------------------------------- |
|
|
13
|
+
| `series` | `ChartSeries<string>` | required | `{ label, points, pattern? }` — a series, category axis. |
|
|
14
|
+
| `locale` | `string` | required | Locale used to format numbers. |
|
|
15
|
+
| `label` | `string` | required | Accessible name of the chart. |
|
|
16
|
+
| `tableCaption` | `string` | required | Caption of the `sr-only` table. |
|
|
17
|
+
| `xColumn` | `string` | required | Header of that table's x-axis column. |
|
|
18
|
+
| `emptyMessage` | `string` | required | Message shown when the series is empty. |
|
|
19
|
+
| `yTickCount` | `number` | `5` | Target number of ticks on the y-axis. |
|
|
20
|
+
| `size` | `{ width: number; height: number } \| null` | `null` | Explicit dimensions — reserved for server rendering, tests. |
|
|
21
|
+
| `heading` | `string` | `''` | Block title. Empty by default: no header is rendered without it. |
|
|
22
|
+
| `headingLevel` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | `2` | Level of the rendered heading. |
|
|
23
|
+
| `headline` | `string` | `''` | Current value, already formatted — "360 GiB". |
|
|
24
|
+
| `trend` | `string` | `''` | Change over the period, already formatted. |
|
|
25
|
+
|
|
26
|
+
**Fluid width with a chosen height** — the common case — is achieved by
|
|
27
|
+
setting the height in CSS on the wrapping container, without passing
|
|
28
|
+
`[size]`. See [`../chart-frame/README.md`](../chart/chart-frame/README.md) for
|
|
29
|
+
the full sizing contract and hover behavior.
|
|
30
|
+
|
|
31
|
+
## Example
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<div style="height: 18rem">
|
|
35
|
+
<gbt-bar-chart
|
|
36
|
+
[series]="{ label: 'Requêtes', points: [{ x: 'Lun', y: 12 }, { x: 'Mar', y: 40 }] }"
|
|
37
|
+
locale="fr-FR"
|
|
38
|
+
label="Requêtes par jour"
|
|
39
|
+
tableCaption="Détail des requêtes par jour"
|
|
40
|
+
xColumn="Jour"
|
|
41
|
+
emptyMessage="Aucune donnée"
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
```
|