@masmarino/gabarit 2.0.0 → 2.1.1
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 +131 -85
- 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 +475 -0
- package/fesm2022/masmarino-gabarit-autocomplete.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit-avatar-group.mjs +202 -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 +1242 -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 +16 -2
- 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 +24 -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 +464 -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 +142 -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 +512 -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 +185 -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/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 +329 -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/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 +140 -0
- package/types/masmarino-gabarit-avatar-group.d.ts +60 -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 +399 -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 +2 -1
- 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 +14 -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 +93 -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 +33 -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 +146 -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 +39 -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 -6599
- package/user-chip/README.md +42 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# PasskeySettings
|
|
2
|
+
|
|
3
|
+
The account settings card of the signed-in user's **passkeys** (WebAuthn): the keys already
|
|
4
|
+
registered (name, when each was added, when it was last used), adding a new one, and deleting one.
|
|
5
|
+
It is the second factor next to the authenticator app of [`gbt-mfa-settings`](../mfa-settings/mfa-settings.ts):
|
|
6
|
+
the two cards sit side by side on an account security page and coordinate through the root-provided
|
|
7
|
+
`MfaSettingsState`.
|
|
8
|
+
|
|
9
|
+
**Selector**: `gbt-passkey-settings`
|
|
10
|
+
|
|
11
|
+
## States
|
|
12
|
+
|
|
13
|
+
| State | What shows |
|
|
14
|
+
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| loading | Two skeleton rows and a polite status (`labels.loading`), outside any `aria-busy` region. |
|
|
16
|
+
| failed | An error alert (`role="alert"`) with a Retry button, which reads the status again. |
|
|
17
|
+
| ready | The list (`ul`, named by `labels.listLabel`, the count beside the card heading) or the empty state (`labels.emptyHeading`), a polite result line, then "Add a passkey" — or, in its place, the add form. Each row opens its own delete prompt. |
|
|
18
|
+
| revoked | After a successful delete (the server revoked every session, this one included): an inert card, only "You have been signed out" (`labels.signedOut`), no list and no action left. `sessionRevoked` fires too: the card cannot clear the application's session itself. |
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
| Input | Type | Default | Role |
|
|
23
|
+
| -------- | -------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `labels` | `Partial<PasskeySettingsLabels>` | `{}` | Strings to change, string by string, over `provideAuthLabels({ passkeySettings })` and the English defaults (`DEFAULT_PASSKEY_SETTINGS_LABELS`). |
|
|
25
|
+
| `locale` | `string \| null` | `null` | The locale of the dates (relative times such as "2 hr. ago", dates such as `03/12/2025`, the exact date and time on hover). `null`: Angular's `LOCALE_ID`. |
|
|
26
|
+
|
|
27
|
+
## Outputs
|
|
28
|
+
|
|
29
|
+
| Output | Payload | Role |
|
|
30
|
+
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `sessionRevoked` | `void` | A passkey was deleted: the server revoked every session of the account, this one included. Sign out locally and go to the sign-in page (when the key was the last factor, the user goes through a new enrolment at the next sign-in). Bind it: the card only turns inert (`revoked`). |
|
|
32
|
+
|
|
33
|
+
## Slots
|
|
34
|
+
|
|
35
|
+
None.
|
|
36
|
+
|
|
37
|
+
## Dependencies (injection)
|
|
38
|
+
|
|
39
|
+
| Token | Required | Role |
|
|
40
|
+
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `MFA_PORT` | yes | `status`, `startPasskeyRegistration`, `finishPasskeyRegistration`, `deletePasskey` (see `MfaPort`). |
|
|
42
|
+
| `AUTH_PORT` | no | Only `authConfig()`, read alongside the status: `passkeysAvailable: false` blocks adding. Without an `AUTH_PORT`, or when the config cannot be read, the availability is unknown and adding is allowed. |
|
|
43
|
+
| `MfaSettingsState` | root | Shared with `gbt-mfa-settings`. Nothing to provide; provide it on the page (`providers: [MfaSettingsState]`) to scope it. |
|
|
44
|
+
| `AUTH_LABELS` | no | The application-wide strings (`provideAuthLabels`). |
|
|
45
|
+
|
|
46
|
+
## Behaviour
|
|
47
|
+
|
|
48
|
+
- **Adding** opens an inline form in place of the button: an optional name (the placeholder and the
|
|
49
|
+
default name are `labels.defaultPasskeyName`, trimmed, at most 40 characters counted as code
|
|
50
|
+
points, no control characters) and the **current password**. The server checks the password on
|
|
51
|
+
`startPasskeyRegistration` before any ceremony (a stolen session alone must not plant a key); the
|
|
52
|
+
browser's prompt then opens (`labels.promptOpen` is said politely meanwhile) and
|
|
53
|
+
`finishPasskeyRegistration` receives the credential and the name. The new key joins the list, the
|
|
54
|
+
result line announces it, and the focus moves to its row.
|
|
55
|
+
- **Failures** of adding: a wrong password is an error under the password field (refocused); 429, 503
|
|
56
|
+
(passkeys unavailable), too many passkeys, a duplicate (409 or the browser's `InvalidStateError`)
|
|
57
|
+
and any other failure are an alert above the form, the focus back on the submit button. A dismissed
|
|
58
|
+
browser prompt is a quiet `info` note (`role="status"`), and the password is kept for a one-click
|
|
59
|
+
retry.
|
|
60
|
+
- **Leaving the form** while a request or the browser's prompt is under way is allowed: a late answer
|
|
61
|
+
is dropped (no prompt opens, nothing is listed). A key whose finish still succeeded is counted in
|
|
62
|
+
`MfaSettingsState`.
|
|
63
|
+
- **Deleting** opens a password prompt under that row (a warning alert first when it is the account's
|
|
64
|
+
last factor: one key and no authenticator app, as read or as changed by the sibling card), then a
|
|
65
|
+
confirmation dialog that says every device is signed out. Confirming calls `deletePasskey` once;
|
|
66
|
+
success emits `sessionRevoked`. A wrong password, a 429 or a server failure bring the user back to
|
|
67
|
+
the prompt with the message; a 404 (already gone) takes the key off the list and announces it,
|
|
68
|
+
nobody is signed out.
|
|
69
|
+
- **Where adding is impossible** (a browser without WebAuthn, or `passkeysAvailable: false`), an
|
|
70
|
+
information note says why and the button is disabled; the keys stay listed and deletable.
|
|
71
|
+
- **One prompt at a time**: opening the add form closes a delete prompt and the reverse; when the app
|
|
72
|
+
card takes the form (`MfaSettingsState.formOwner`), this card's open prompts close quietly; while the
|
|
73
|
+
app card is mid-enrolment (`appFlowActive`), "Add a passkey" is disabled with a hint. At most one
|
|
74
|
+
primary button is on screen.
|
|
75
|
+
- **Secrets**: passwords live in signals until their request answers or the form closes, and are
|
|
76
|
+
cleared when the component is destroyed; the credential the browser returns is never stored.
|
|
77
|
+
- **Dates**: an addition or a last use older than 30 days is shown as a date (`labels.added(true)`,
|
|
78
|
+
"Added on"), a recent one as a relative time (`labels.added(false)`, "Added"); the `<time>` element
|
|
79
|
+
carries the ISO date and the exact date and time as its `title`.
|
|
80
|
+
|
|
81
|
+
## Example
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// app.config.ts
|
|
85
|
+
import { AUTH_PORT, MFA_PORT, provideAuthLabels } from '@masmarino/gabarit'
|
|
86
|
+
|
|
87
|
+
export const appConfig: ApplicationConfig = {
|
|
88
|
+
providers: [
|
|
89
|
+
{ provide: MFA_PORT, useClass: HttpMfaPort }, // your adapter over HttpClient
|
|
90
|
+
{ provide: AUTH_PORT, useClass: HttpAuthPort }, // optional here: only authConfig() is read
|
|
91
|
+
provideAuthLabels({ passkeySettings: { heading: "Clés d'accès" /* … */ } }),
|
|
92
|
+
],
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// account-security.page.ts
|
|
98
|
+
@Component({
|
|
99
|
+
imports: [MfaSettings, PasskeySettings],
|
|
100
|
+
template: `
|
|
101
|
+
<gbt-mfa-settings (sessionRevoked)="signOut()" />
|
|
102
|
+
<gbt-passkey-settings locale="fr" (sessionRevoked)="signOut()" />
|
|
103
|
+
`,
|
|
104
|
+
})
|
|
105
|
+
export class AccountSecurityPage {
|
|
106
|
+
private readonly session = inject(SessionService)
|
|
107
|
+
private readonly router = inject(Router)
|
|
108
|
+
|
|
109
|
+
signOut(): void {
|
|
110
|
+
this.session.clear()
|
|
111
|
+
this.router.navigateByUrl('/login')
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The card never navigates and never touches storage: signing out after a deletion is the page's job.
|
|
117
|
+
|
|
118
|
+
## Accessibility
|
|
119
|
+
|
|
120
|
+
See [AUDIT.md](AUDIT.md).
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# PieChart
|
|
2
|
+
|
|
3
|
+
A pie or donut chart for showing how a total splits across categories
|
|
4
|
+
— traffic sources, storage by type, budget allocation. One component
|
|
5
|
+
covers both shapes: `innerRadiusRatio` at `0` draws a full pie, a
|
|
6
|
+
value like `0.6` draws a donut.
|
|
7
|
+
|
|
8
|
+
Distinct from `BarChart`/`LineChart`/`TimelineChart`: those are
|
|
9
|
+
cartesian (an x/y axis, built on `ChartFrame`), while `PieChart` has
|
|
10
|
+
no axis at all — it shares that trait with `FunnelChart`, and follows
|
|
11
|
+
the same architecture (see "Why not `ChartFrame`" below).
|
|
12
|
+
|
|
13
|
+
**Selector**: `gbt-pie-chart`
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
| Input | Type | Role |
|
|
18
|
+
| -------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------- |
|
|
19
|
+
| `slices` | `{ label: string; value: number }[]` | Required. One entry per category. |
|
|
20
|
+
| `label` | `string` | Required. Accessible name of the chart (`<svg role="group">`). |
|
|
21
|
+
| `locale` | `string` | Required. Locale used to format numbers and percentages. |
|
|
22
|
+
| `emptyMessage` | `string` | Required. Message shown when `slices` is empty. |
|
|
23
|
+
| `tableCaption` | `string` | Required. Caption of the `sr-only` data table. |
|
|
24
|
+
| `categoryColumn` | `string` | Required. Header of that table's category column. |
|
|
25
|
+
| `valueColumn` | `string` | Required. Header of that table's value column. |
|
|
26
|
+
| `shareColumn` | `string` | Required. Header of that table's share-of-total column. |
|
|
27
|
+
| `sliceAnnouncement` | `(label: string, value: string, share: string) => string` | Required. Formats the live-region message for the hovered/focused slice. |
|
|
28
|
+
| `innerRadiusRatio` | `number` | Optional, defaults to `0`. `0` = pie, e.g. `0.6` = donut. |
|
|
29
|
+
|
|
30
|
+
## Example
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<gbt-pie-chart
|
|
34
|
+
[slices]="trafficSources"
|
|
35
|
+
label="Répartition du trafic"
|
|
36
|
+
locale="fr-FR"
|
|
37
|
+
emptyMessage="Aucune donnée."
|
|
38
|
+
tableCaption="Répartition du trafic"
|
|
39
|
+
categoryColumn="Source"
|
|
40
|
+
valueColumn="Visites"
|
|
41
|
+
shareColumn="Part"
|
|
42
|
+
[sliceAnnouncement]="sliceAnnouncement"
|
|
43
|
+
[innerRadiusRatio]="0.6"
|
|
44
|
+
/>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Behavior
|
|
48
|
+
|
|
49
|
+
- Each slice's angle is its share of the sum of all `slices` values.
|
|
50
|
+
An all-zero total renders every slice at 0% rather than dividing by
|
|
51
|
+
zero.
|
|
52
|
+
- A slice's percentage is written directly next to it only once it
|
|
53
|
+
reaches 15% of the total — below that, the number on the slice would
|
|
54
|
+
overlap its neighbors. Every slice's exact share is always available
|
|
55
|
+
in the legend and in the `sr-only` table regardless of this
|
|
56
|
+
threshold.
|
|
57
|
+
- Hovering or focusing a slice highlights it **and** its matching
|
|
58
|
+
legend entry at the same time, in both directions — hovering the
|
|
59
|
+
legend entry highlights the slice too. One shared `activeIndex`
|
|
60
|
+
drives both.
|
|
61
|
+
- Up to 6 slices get a distinguishable color from `--chart-series-1`
|
|
62
|
+
through `--chart-series-6`; beyond that the palette cycles and a
|
|
63
|
+
console warning is logged in dev mode, the same convention
|
|
64
|
+
`LineChart` uses for its own `MAX_SERIES`.
|
|
65
|
+
- The empty state (`ChartEmpty`) gets a small pie icon — a circle with
|
|
66
|
+
one filled wedge, not a chart-agnostic placeholder — via
|
|
67
|
+
`ChartEmpty`'s `[gbtChartEmptyIcon]` projection slot.
|
|
68
|
+
|
|
69
|
+
## Why not `ChartFrame`
|
|
70
|
+
|
|
71
|
+
The shared cartesian base (`ChartFrame`, `ChartContext`, `ChartAxis`,
|
|
72
|
+
`ChartTooltip`) computes everything — scales, tick positions, the
|
|
73
|
+
active point's pixel offset — from an x/y axis. A pie chart has
|
|
74
|
+
neither: its geometry is angles around a center, not positions along
|
|
75
|
+
axes. Forcing it through that base would mean fighting types built for
|
|
76
|
+
a different geometry rather than reusing anything real, so `PieChart`
|
|
77
|
+
instead follows the one existing precedent for a categorical,
|
|
78
|
+
axis-less chart in this library, `FunnelChart`: no `ChartFrame`, a
|
|
79
|
+
locally-owned `activeIndex` signal, and a hand-rolled `aria-live`
|
|
80
|
+
announcement, reusing only the genuinely generic building blocks
|
|
81
|
+
(`ChartEmpty`, `ChartTable`, and now `ChartLegend`).
|
|
82
|
+
|
|
83
|
+
## Accessibility
|
|
84
|
+
|
|
85
|
+
See `AUDIT.md` for the full RGAA checklist.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Popover
|
|
2
|
+
|
|
3
|
+
Generic floating panel that wraps any projected trigger and shows
|
|
4
|
+
arbitrary projected content near it, opened/closed by a click — for
|
|
5
|
+
rich content (a mini-form, a list of actions, a long text) that
|
|
6
|
+
`Tooltip`'s hover-triggered short text doesn't fit.
|
|
7
|
+
|
|
8
|
+
**Selector**: `gbt-popover` (`exportAs="gbtPopover"`)
|
|
9
|
+
|
|
10
|
+
## Inputs
|
|
11
|
+
|
|
12
|
+
| Input | Type | Default | Role |
|
|
13
|
+
| ------- | ----------------- | --------- | -------------------------------------------------------- |
|
|
14
|
+
| `align` | `'start' \| 'end'` | `'start'` | Aligns the panel's left or right edge with the trigger's. |
|
|
15
|
+
|
|
16
|
+
## Content
|
|
17
|
+
|
|
18
|
+
| Slot | Role |
|
|
19
|
+
| ------------------------------ | ----------------------------------------------------------------- |
|
|
20
|
+
| Default (unmarked) | The trigger — any element(s), shown as-is, click anywhere toggles the panel. |
|
|
21
|
+
| `[popover-content]` | The panel's body — fully free-form, no role or structure imposed. |
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<gbt-popover #pop="gbtPopover">
|
|
27
|
+
<button type="button" [attr.aria-expanded]="pop.open()" [attr.aria-controls]="pop.panelId">
|
|
28
|
+
Options
|
|
29
|
+
</button>
|
|
30
|
+
<div popover-content>
|
|
31
|
+
<p>Any content: a form, a list, plain text…</p>
|
|
32
|
+
<button type="button" (click)="pop.close()">Close</button>
|
|
33
|
+
</div>
|
|
34
|
+
</gbt-popover>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Behavior
|
|
38
|
+
|
|
39
|
+
- Opens on a click anywhere inside the trigger slot; closes on an
|
|
40
|
+
outside click or `Escape` — never on a click inside the panel's own
|
|
41
|
+
content, since that content can be a form or contain its own buttons.
|
|
42
|
+
- `Escape` returns focus to the first focusable element found inside
|
|
43
|
+
the trigger slot.
|
|
44
|
+
- No collision/flip handling if the panel would render off-screen —
|
|
45
|
+
the same trade-off `gbt-menu` already makes; choose an `align` that
|
|
46
|
+
fits the layout.
|
|
47
|
+
|
|
48
|
+
## Accessibility
|
|
49
|
+
|
|
50
|
+
`gbt-popover` wraps arbitrary projected content, so it cannot reach
|
|
51
|
+
into it to set `aria-expanded`/`aria-controls` on your own trigger
|
|
52
|
+
element — the same limitation `gbt-tooltip` has for `aria-describedby`.
|
|
53
|
+
Wire them yourself using the instance exposed by `exportAs="gbtPopover"`:
|
|
54
|
+
|
|
55
|
+
- `pop.open()` — a signal, `true` while the panel is shown.
|
|
56
|
+
- `pop.panelId` — the panel's DOM id, for `aria-controls`.
|
|
57
|
+
- `pop.toggle()` / `pop.close()` — for a close button inside your own
|
|
58
|
+
content (see the example above).
|
|
59
|
+
|
|
60
|
+
The panel itself carries no ARIA role — it's your content, so it's
|
|
61
|
+
your responsibility to give it one if it needs it (e.g. `role="dialog"`
|
|
62
|
+
for a form, or leave it out entirely for a plain block of text).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# RadioGroup
|
|
2
|
+
|
|
3
|
+
Groupe de boutons radio pour un choix exclusif parmi plusieurs options.
|
|
4
|
+
S'intègre aux formulaires Angular via `ControlValueAccessor`, comme
|
|
5
|
+
`Checkbox` et `Select`.
|
|
6
|
+
|
|
7
|
+
**Selector**: `gbt-radio-group`
|
|
8
|
+
|
|
9
|
+
## Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Role |
|
|
12
|
+
| -------------- | -------------------------------- | ---------- | -------------------------------------------------------- |
|
|
13
|
+
| `label` | `string` | required | Légende du groupe (`<legend>`). |
|
|
14
|
+
| `options` | `RadioOption<T>[]` | required | Options du groupe. |
|
|
15
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Disposition des options. |
|
|
16
|
+
| `disabled` | `boolean` | `false` | Désactive tout le groupe. |
|
|
17
|
+
| `required` | `boolean` | `false` | Affiche un `*` à côté du label. |
|
|
18
|
+
| `errorMessage` | `string \| null` | `null` | Message d'erreur, associé via `aria-describedby`. |
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
interface RadioOption<T = string> {
|
|
22
|
+
value: T
|
|
23
|
+
label: string
|
|
24
|
+
disabled?: boolean // désactive uniquement cette option
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Exemple
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<gbt-radio-group label="Statut" [options]="statusOptions" formControlName="status" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
statusOptions: RadioOption[] = [
|
|
36
|
+
{ value: 'draft', label: 'Brouillon' },
|
|
37
|
+
{ value: 'published', label: 'Publié' },
|
|
38
|
+
{ value: 'archived', label: 'Archivé' },
|
|
39
|
+
]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Accessibilité
|
|
43
|
+
|
|
44
|
+
Boutons radio natifs (`<input type="radio">`) partageant le même
|
|
45
|
+
`name`, dans un `<fieldset>`/`<legend>` — le regroupement, l'état
|
|
46
|
+
coché mutuellement exclusif et la navigation clavier (flèches) sont
|
|
47
|
+
gérés nativement par le navigateur, sans JavaScript additionnel.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# SaveStatus
|
|
2
|
+
|
|
3
|
+
The save state of a field or form that saves on its own: "Saving…", "Saved", "Not saved".
|
|
4
|
+
|
|
5
|
+
**Selector**: `gbt-save-status`
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
| Input | Type | Default | Role |
|
|
10
|
+
| ------------- | ------------------------------------------ | ------------- | ------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| `state` | `'idle' \| 'saving' \| 'saved' \| 'error'` | `'idle'` | The state to show. Set it from your save logic; nothing resets itself. |
|
|
12
|
+
| `savingLabel` | `string` | `'Saving…'` | Text of `saving`. |
|
|
13
|
+
| `savedLabel` | `string` | `'Saved'` | Text of `saved`. |
|
|
14
|
+
| `errorLabel` | `string` | `'Not saved'` | Text of `error`. |
|
|
15
|
+
| `message` | `string \| null` | `null` | Replaces the current state's text with a specific one; keeps its icon and colour. Ignored while `idle`. |
|
|
16
|
+
|
|
17
|
+
## The live region
|
|
18
|
+
|
|
19
|
+
The text lives in a `role="status"` element that is **always rendered**, also when `idle` (empty). A live
|
|
20
|
+
region only announces changes if it was already in the accessibility tree, so never put the component
|
|
21
|
+
behind an `@if` on the state: bind `[state]` instead. `idle` keeps the 20 px line, so nothing moves when a
|
|
22
|
+
state appears. The host carries no role; the inner `.gbt-save-status` has `data-state`.
|
|
23
|
+
|
|
24
|
+
Each state has an icon as well as text and colour: a spinning ring (a static ring under
|
|
25
|
+
`prefers-reduced-motion`), a check, an alert.
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<gbt-input label="Instance name" [(ngModel)]="name" (blur)="save()" />
|
|
31
|
+
<gbt-save-status
|
|
32
|
+
[state]="nameState()"
|
|
33
|
+
savingLabel="Enregistrement…"
|
|
34
|
+
savedLabel="Enregistré"
|
|
35
|
+
errorLabel="Non enregistré"
|
|
36
|
+
/>
|
|
37
|
+
|
|
38
|
+
<!-- A form-level result with its own wording -->
|
|
39
|
+
<gbt-save-status [state]="result().state" [message]="result().message" />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Accessibility
|
|
43
|
+
|
|
44
|
+
See [AUDIT.md](AUDIT.md).
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# SearchBar
|
|
2
|
+
|
|
3
|
+
Search field with grouped or flat results, keyboard navigation, and a
|
|
4
|
+
blurred backdrop over the rest of the page while searching.
|
|
5
|
+
|
|
6
|
+
**Selector**: `gbt-search-bar`
|
|
7
|
+
|
|
8
|
+
Up/down arrows to move through results, Enter to select, Escape to
|
|
9
|
+
close. The trigger and the results panel stay sharp above the backdrop;
|
|
10
|
+
the rest of the page blurs behind it.
|
|
11
|
+
|
|
12
|
+
## Inputs
|
|
13
|
+
|
|
14
|
+
| Input | Type | Default | Role |
|
|
15
|
+
| --------------------- | ----------------------------------- | ------------------------------ | ------------------------------------------------------------------------ |
|
|
16
|
+
| `id` | `string` | generated (`gbt-search-bar-N`) | Prefix of the generated DOM ids. |
|
|
17
|
+
| `results` | `T[] \| null` | `null` | Flat results — an alternative to `groupedResults`. |
|
|
18
|
+
| `groupedResults` | `SearchResultCategory<T>[] \| null` | `null` | Results grouped by category — `{ label, icon?, items }`. |
|
|
19
|
+
| `placeholder` | `string` | `'Search…'` | Field placeholder text. |
|
|
20
|
+
| `ariaLabel` | `string` | `''` | Accessible name of the field, when the placeholder isn't enough. |
|
|
21
|
+
| `displayFn` | `(item: T) => string` | `String(item)` | Formats a result into displayed text. |
|
|
22
|
+
| `itemTemplate` | `TemplateRef<unknown>` | — | Custom template for rendering a result. |
|
|
23
|
+
| `keepQueryOnSelect` | `boolean` | `false` | Keeps the chosen result's text in the field, instead of clearing it. |
|
|
24
|
+
| `noResultsMessage` | `string` | `'No results'` | Message when there are no results. |
|
|
25
|
+
| `noResultsHint` | `string` | `'Try a different search.'` | Subtext under the "no results" message. |
|
|
26
|
+
| `clearLabel` | `string` | `'Clear search'` | Accessible name of the clear button. |
|
|
27
|
+
| `resultsAnnouncement` | `(count: number) => string` | `` `${count} result(s)` `` | Live ARIA announcement of the result count. |
|
|
28
|
+
| `navigateHint` | `string` | `'Navigate'` | Footer text, keyboard hint. |
|
|
29
|
+
| `selectHint` | `string` | `'Select'` | Footer text, keyboard hint. |
|
|
30
|
+
| `closeHint` | `string` | `'Close'` | Footer text, keyboard hint. |
|
|
31
|
+
| `collapsible` | `boolean \| 'narrow'` | `false` | Compact mode for a mobile header (see below). |
|
|
32
|
+
| `expanded` | `boolean` (model) | `false` | Whether the field is shown while `collapsible`. Two-way: `[(expanded)]`. |
|
|
33
|
+
| `openLabel` | `string` | `'Search'` | Accessible name of the compact icon button. |
|
|
34
|
+
| `closeLabel` | `string` | `'Close search'` | Accessible name of the compact field's back-arrow close button. |
|
|
35
|
+
|
|
36
|
+
## Outputs
|
|
37
|
+
|
|
38
|
+
| Output | Type | Role |
|
|
39
|
+
| -------------- | -------- | ------------------------------------- |
|
|
40
|
+
| `queryChange` | `string` | Emitted on every keystroke. |
|
|
41
|
+
| `itemSelected` | `T` | Emitted when a result is selected. |
|
|
42
|
+
| `clear` | `void` | Emitted on click of the clear button. |
|
|
43
|
+
|
|
44
|
+
## Compact mode (`collapsible`)
|
|
45
|
+
|
|
46
|
+
For a mobile header where the field cannot stay inline: the field is replaced by an icon button (44 px) that
|
|
47
|
+
expands it over the row and focuses it. Off by default: the field is always shown.
|
|
48
|
+
|
|
49
|
+
- `collapsible` (or `[collapsible]="true"`): always compact.
|
|
50
|
+
- `collapsible="narrow"`: compact only up to 768 px, the full field above (pure CSS: nothing to observe).
|
|
51
|
+
- `[(expanded)]` lets the header hide its other items (title, account menu) while the search has the row.
|
|
52
|
+
- Escape folds the field back (with results open, the first Escape closes them); so does leaving the field while it
|
|
53
|
+
is empty, and choosing a result (unless `keepQueryOnSelect`). Escape returns focus to the icon button.
|
|
54
|
+
- The icon button is a native `<button aria-expanded="false" aria-controls>` named by `openLabel`; it is removed
|
|
55
|
+
from the tree while the field is shown.
|
|
56
|
+
- While the field is shown, a back-arrow button named by `closeLabel` (default `'Close search'`) stands in for the
|
|
57
|
+
search glyph and folds it back, keeping the typed text: on a phone there is no Escape key, and leaving a field
|
|
58
|
+
that holds text does not fold it. It is not rendered above 768 px in `narrow` mode.
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<header class="app-header">
|
|
62
|
+
@if (!searchOpen()) {
|
|
63
|
+
<h1>Dashboard</h1>
|
|
64
|
+
}
|
|
65
|
+
<gbt-search-bar
|
|
66
|
+
collapsible="narrow"
|
|
67
|
+
[(expanded)]="searchOpen"
|
|
68
|
+
openLabel="Rechercher"
|
|
69
|
+
[groupedResults]="results()"
|
|
70
|
+
/>
|
|
71
|
+
</header>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Example
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<gbt-search-bar
|
|
78
|
+
[groupedResults]="categories"
|
|
79
|
+
[displayFn]="(depot) => depot.nom"
|
|
80
|
+
ariaLabel="Rechercher un dépôt"
|
|
81
|
+
placeholder="Rechercher…"
|
|
82
|
+
(itemSelected)="ouvrir($event)"
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# SecretReveal
|
|
2
|
+
|
|
3
|
+
A secret shown once or on demand: an API token, a runner registration token, a recovery code. Masked
|
|
4
|
+
until the user shows it; copies whether it is shown or not.
|
|
5
|
+
|
|
6
|
+
**Selector**: `gbt-secret-reveal`. Built on [`gbt-button`](../button/README.md) (show / hide) and
|
|
7
|
+
[`gbt-copy-button`](../copy-button/README.md).
|
|
8
|
+
|
|
9
|
+
## Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Role |
|
|
12
|
+
| ------------- | ---------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `value` | `string` | — | Required. The secret. |
|
|
14
|
+
| `revealed` | `boolean` (model) | `false` | Whether the secret is shown; two-way `[(revealed)]`. Start it `true` for a one-time secret. |
|
|
15
|
+
| `label` | `string \| null` | `null` | Visible label above the field; it also names the group. |
|
|
16
|
+
| `showLabel` | `string` | `'Show the secret'` | Accessible name of the toggle while masked. |
|
|
17
|
+
| `hideLabel` | `string` | `'Hide the secret'` | Accessible name of the toggle while shown. |
|
|
18
|
+
| `hiddenLabel` | `string` | `'Secret hidden'` | Read by screen readers in place of the bullets. |
|
|
19
|
+
| `copyLabel` | `string` | `'Copy the secret'` | Accessible name of the copy button. |
|
|
20
|
+
| `copiedText` | `string` | `'Copied'` | Confirmation after a copy. |
|
|
21
|
+
| `failedText` | `string` | `'Copy failed, secret shown and selected'` | Message when the copy is refused. |
|
|
22
|
+
| `feedbackMs` | `number` | `2000` | How long the confirmation stays. |
|
|
23
|
+
| `feedback` | `'bubble' \| 'inline' \| 'hidden'` | `'bubble'` | Where the confirmation is drawn. |
|
|
24
|
+
| `maskLength` | `number` | `24` | Bullets drawn while masked (fixed: the real length is not disclosed). |
|
|
25
|
+
|
|
26
|
+
## Outputs
|
|
27
|
+
|
|
28
|
+
| Output | Payload | Role |
|
|
29
|
+
| ---------------- | --------- | ------------------------------------------------------------------- |
|
|
30
|
+
| `copied` | `string` | The copied secret. |
|
|
31
|
+
| `copyFailed` | `void` | Neither copy API worked: the secret has been revealed and selected. |
|
|
32
|
+
| `revealedChange` | `boolean` | The user showed or hid the secret (the model's change event). |
|
|
33
|
+
|
|
34
|
+
## Behaviour
|
|
35
|
+
|
|
36
|
+
- **Masked, the secret is not in the DOM** (only bullets, `aria-hidden`, and a visually hidden `hiddenLabel`):
|
|
37
|
+
it cannot be read by assistive technology, found by in-page search or taken from a DOM snapshot.
|
|
38
|
+
- The copy button copies the real secret without showing it.
|
|
39
|
+
- A refused copy (plain-HTTP page, permissions) reveals the secret and selects it for a manual Ctrl+C.
|
|
40
|
+
- The toggle carries `aria-controls` (the value element) and swaps its accessible name; it is not also
|
|
41
|
+
`aria-pressed` (one signal, not two).
|
|
42
|
+
|
|
43
|
+
## Example
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<gbt-secret-reveal
|
|
47
|
+
label="Runner token"
|
|
48
|
+
showLabel="Show the token"
|
|
49
|
+
hideLabel="Hide the token"
|
|
50
|
+
hiddenLabel="Token hidden"
|
|
51
|
+
copyLabel="Copy the token"
|
|
52
|
+
[value]="runner.token"
|
|
53
|
+
[revealed]="true"
|
|
54
|
+
(copied)="tokenCopied.set(true)"
|
|
55
|
+
/>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Accessibility
|
|
59
|
+
|
|
60
|
+
See [AUDIT.md](AUDIT.md). Localise every string input.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# SegmentedControl
|
|
2
|
+
|
|
3
|
+
Compact, exclusive-choice button group — e.g. switching a view between
|
|
4
|
+
"Day / Week / Month". Unlike `Tabs`, it carries no navigation
|
|
5
|
+
semantics (`role="radiogroup"`, not `role="tablist"`): it's a value
|
|
6
|
+
selector, not a way to move between different page contents.
|
|
7
|
+
|
|
8
|
+
**Selector**: `gbt-segmented-control`
|
|
9
|
+
|
|
10
|
+
## Inputs
|
|
11
|
+
|
|
12
|
+
| Input | Type | Default | Role |
|
|
13
|
+
| ----------- | --------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
14
|
+
| `options` | `{ value: T; label: string; disabled?: boolean }[]` | required | The choices, in display order. |
|
|
15
|
+
| `value` | `T` (model) | required | The selected option's value. Bind `[value]`/`[(value)]` to control or observe it from outside. |
|
|
16
|
+
| `ariaLabel` | `string` | `''` | Accessible name of the group — there's no visible legend, so provide one (e.g. "Période"). |
|
|
17
|
+
| `disabled` | `boolean` | `false` | Disables every option at once. |
|
|
18
|
+
| `label` | `string` | `''` | Visible label above the control; it names the group (`aria-labelledby`) and takes over from `ariaLabel`. |
|
|
19
|
+
| `fullWidth` | `boolean` | `false` | Fills the container; the options share the width equally. |
|
|
20
|
+
| `wrap` | `boolean` | `false` | Lets the options flow onto several rows when they do not fit. A label never breaks in the middle. |
|
|
21
|
+
| `size` | `'md' \| 'sm'` | `'md'` | Both sizes are 32px tall, track included (`--gbt-control-height-sm`: level with a small button and the `sm` fields); `sm` has smaller text and tighter sides. |
|
|
22
|
+
| `tinted` | `boolean` | `false` | Draws the track with `--bg-track` (a step darker than `--bg-panel`) so it stays visible on a panel and on the page background. |
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<gbt-segmented-control
|
|
28
|
+
[options]="[
|
|
29
|
+
{ value: 'day', label: 'Jour' },
|
|
30
|
+
{ value: 'week', label: 'Semaine' },
|
|
31
|
+
{ value: 'month', label: 'Mois' },
|
|
32
|
+
]"
|
|
33
|
+
[(value)]="period"
|
|
34
|
+
ariaLabel="Période"
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Layout options
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<!-- visible label + full width, tinted track -->
|
|
42
|
+
<gbt-segmented-control label="Sort" fullWidth tinted [options]="sorts" [(value)]="sort" />
|
|
43
|
+
|
|
44
|
+
<!-- state tabs with counts in a narrow column -->
|
|
45
|
+
<gbt-segmented-control wrap size="sm" ariaLabel="Result type" [options]="types" [(value)]="type" />
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **Track token.** The default track is `--bg-panel`, which is the page background
|
|
49
|
+
in the app shell and vanishes on a panel. `tinted` uses the semantic token
|
|
50
|
+
`--bg-track` (`slate-200` in light, `graphite-700` in dark; `contrast.spec.ts` checks the
|
|
51
|
+
option text on it and that it stays distinguishable from the page and from
|
|
52
|
+
`--bg-panel`).
|
|
53
|
+
- `label` gives the group one visible name, referenced by `aria-labelledby` — the
|
|
54
|
+
alternative is an `ariaLabel` with no visible text.
|
|
55
|
+
- With `wrap`, arrow keys still follow the DOM order, row after row.
|
|
56
|
+
|
|
57
|
+
## Behavior
|
|
58
|
+
|
|
59
|
+
- Left/right arrow keys (also up/down) move selection _and_ focus
|
|
60
|
+
together, immediately — the same behavior as a native
|
|
61
|
+
`<input type="radio">` group, not `Tabs`' "arrows move focus only,
|
|
62
|
+
the option was already selected" (there is nothing to "activate"
|
|
63
|
+
separately). `Home`/`End` jump to the first/last enabled option.
|
|
64
|
+
Disabled options are skipped when navigating.
|
|
65
|
+
- Roving tabindex: only the selected option is a tab stop.
|
|
66
|
+
|
|
67
|
+
## Why not a `ControlValueAccessor`
|
|
68
|
+
|
|
69
|
+
`RadioGroup` already covers a real form field. `SegmentedControl`'s
|
|
70
|
+
primary use is switching a displayed view (a chart's period, a list's
|
|
71
|
+
sort order) — a `model()`-based `value`, the same pattern `Tabs` uses
|
|
72
|
+
for `activeIndex`, fits that without pulling in Angular Forms. Use
|
|
73
|
+
`RadioGroup` instead if you need this exact choice as part of a form.
|
|
74
|
+
|
|
75
|
+
## How many options
|
|
76
|
+
|
|
77
|
+
Designed for a small, fixed set (2–5) shown at a glance. Beyond that,
|
|
78
|
+
the segments get cramped and `Select` becomes the better fit — this
|
|
79
|
+
isn't enforced by the component, it's a design judgment call.
|