From 4449d8baf6506ffc82f1609ffd7c83e5cb94631a Mon Sep 17 00:00:00 2001 From: Bryan Cunningham Date: Tue, 19 Aug 2025 15:15:41 -0400 Subject: [PATCH] [CL-689][CL-799] Fix Icon button a11y errors (#15750) * Throw error if appA11yTitle is null in icon button * Add required label input * Fix icon button errors in CL components and storeis * fix popover aria-label errors * remove commented code * add labels to icon buttons in browser * add labels to icon buttons in web * add labels to icon buttons in license * add labels to icon buttons in send * add labels to icon buttons in angular * fix missing pipe error * fix sso icon button missed in error * update labels in vault * add section expand button label * Adding labels to icon buttons * Add lint rule to not allow icon buttons without label input * rename util file * trigger updates on title change * update eslint rule name and folder * add edit collection label to vault headers * fix web header story label * add show/hide summary labels * update summary message * fix breadcrumbs label message * fix JSDoc to use correct input * remove commented code * use label as aria-label always. Remove init function * add moreBreadcrumbs translation message to other apps * add @bitwarden/team-ui-foundation as code owner for component eslint rules * switch title to const variable * add jsdoc comment on what the label input is used for * [PM-22415] Tax ID notifications for Organizations and Providers (#15996) * [NO LOGIC] Rename BillableEntity to BitwardenSubscriber This helps us maintain paraody with server where we call this choice type ISubscriber. I chose BitwardenSubscriber to avoid overlap with RxJS * [NO LOGIC] Move subscriber-billing.client to clients folder * [NO LOGIC] Move organization warnings under organization folder * Move getWarnings from OrganizationBillingApiService to new OrganizationBillingClient I'd like us to move away from stashing so much in libs and utilizing the JsLibServicesModule when it's not necessary to do so. These are invocations used exclusively by the Web Vault and, until that changes, they should be treated as such * Refactor OrganizationWarningsService There was a case added to the Inactive Subscription warning for a free trial, but free trials do not represent inactive subscriptions so this was semantically incorrect. This creates another method that pulls the free trial warning and shows a dialog asking the user to subscribe if they're on one. * Implement Tax ID Warnings throughout Admin Console and Provider Portal * Fix linting error * Jimmy's feedback * remove duplicate messages keys * revert changes to popover stories * add back dupe myItems key for now as it was already here * fix directive type errors * remove variable left in error from merge conflict * revert unintentional change to reports layout * add back reports change --------- Co-authored-by: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> --- .github/CODEOWNERS | 1 + apps/browser/src/_locales/en/messages.json | 4 ++ .../settings/blocked-domains.component.html | 2 +- .../settings/excluded-domains.component.html | 2 +- .../popup/components/pop-out.component.html | 2 +- .../popup/layout/popup-header.component.html | 3 +- .../popup/layout/popup-layout.stories.ts | 32 +++++------- .../add-edit/send-add-edit.component.html | 2 +- .../add-edit/add-edit-v2.component.html | 2 +- .../item-copy-actions.component.html | 30 +++++------ .../item-more-options.component.html | 3 +- .../vault-header-v2.component.html | 2 +- .../vault-list-items-container.component.html | 5 +- .../vault-v2/view-v2/view-v2.component.html | 2 +- .../popup/settings/folders-v2.component.html | 2 +- .../trash-list-items-container.component.html | 3 +- apps/desktop/src/locales/en/messages.json | 4 ++ .../vault-header/vault-header.component.html | 1 + .../manage/group-add-edit.component.html | 2 +- .../manage/groups.component.html | 4 +- .../members/members.component.html | 4 +- .../access-selector-dialog.stories.ts | 2 +- .../access-selector.component.html | 2 +- .../collection-dialog.component.html | 2 +- .../emergency-access-add-edit.component.html | 2 +- .../emergency-access.component.html | 4 +- .../two-factor-setup-yubikey.component.html | 2 +- .../free-bitwarden-families.component.html | 2 +- .../billing-sync-api-key.component.html | 2 +- .../billing-sync-key.component.html | 2 +- .../change-plan-dialog.component.html | 2 +- .../organizations/change-plan.component.html | 2 +- .../sponsoring-org-row.component.html | 2 +- .../pricing-summary.component.html | 4 +- .../reports/reports-layout.component.html | 2 +- .../app/layouts/header/web-header.stories.ts | 2 +- .../product-switcher.component.html | 2 +- .../app/settings/domain-rules.component.html | 3 +- .../src/app/tools/send/send.component.html | 2 +- .../vault-item-dialog.component.html | 2 +- .../vault-cipher-row.component.html | 4 +- .../vault-collection-row.component.html | 2 +- .../vault-items/vault-items.component.html | 2 +- .../vault-header/vault-header.component.html | 2 +- apps/web/src/locales/en/messages.json | 10 ++++ .../device-approvals.component.html | 4 +- .../domain-add-edit-dialog.component.html | 5 +- .../organizations/manage/scim.component.html | 8 +-- .../add-edit-member-dialog.component.html | 2 +- .../providers/manage/members.component.html | 4 +- .../src/app/auth/sso/sso.component.html | 14 ++--- .../clients/manage-clients.component.html | 2 +- .../app-table-row-scrollable.component.html | 2 +- .../overview/section.component.html | 1 + .../dialog/secret-dialog.component.html | 2 +- .../access/access-list.component.html | 6 +-- .../config/config.component.html | 10 +++- .../service-accounts-list.component.html | 6 +-- .../access-policy-selector.component.html | 3 +- .../shared/projects-list.component.html | 9 ++-- .../shared/secrets-list.component.html | 9 ++-- eslint.config.mjs | 6 +++ .../spotlight/spotlight.component.html | 3 +- .../input-password.component.html | 4 +- .../src/a11y/a11y-title.directive.ts | 21 ++++---- .../src/a11y/set-a11y-title-and-aria-label.ts | 16 ++++++ .../components/src/async-actions/in-forms.mdx | 8 ++- .../src/async-actions/in-forms.stories.ts | 7 ++- .../src/async-actions/standalone.mdx | 2 +- .../src/async-actions/standalone.stories.ts | 2 +- .../src/banner/banner.component.html | 3 +- .../breadcrumbs/breadcrumbs.component.html | 1 + .../src/breadcrumbs/breadcrumbs.component.ts | 4 +- .../src/breadcrumbs/breadcrumbs.stories.ts | 13 +++++ .../src/dialog/dialog/dialog.component.html | 3 +- .../src/dialog/dialog/dialog.stories.ts | 10 ++-- .../src/disclosure/disclosure.component.ts | 1 + .../src/disclosure/disclosure.stories.ts | 2 +- .../src/drawer/drawer-header.component.html | 8 +-- .../src/form-field/form-field.stories.ts | 28 +++++----- .../form-field/password-input-toggle.spec.ts | 8 ++- .../password-input-toggle.stories.ts | 4 +- .../src/icon-button/icon-button.component.ts | 25 +++++++-- .../src/icon-button/icon-button.stories.ts | 1 + libs/components/src/item/item.mdx | 4 +- libs/components/src/item/item.stories.ts | 44 ++++++++-------- .../src/navigation/nav-group.component.html | 3 +- .../src/navigation/nav-item.stories.ts | 4 +- .../src/navigation/side-nav.component.html | 2 +- .../src/popover/popover.component.html | 3 +- libs/components/src/section/section.mdx | 2 +- .../components/src/section/section.stories.ts | 16 +++--- .../dialog-virtual-scroll-block.component.ts | 2 +- .../components/kitchen-sink-form.component.ts | 8 ++- .../kitchen-sink-table.component.ts | 2 + .../components/src/toast/toast.component.html | 1 + libs/eslint/components/index.mjs | 3 ++ .../require-label-on-biticonbutton.mjs | 51 +++++++++++++++++++ .../src/components/export.component.html | 2 + ...redential-generator-history.component.html | 2 +- .../src/credential-generator.component.html | 4 +- .../src/password-generator.component.html | 4 +- .../src/username-generator.component.html | 4 +- .../send-add-edit-dialog.component.html | 2 +- .../options/send-options.component.html | 6 +-- .../send-details/send-details.component.html | 2 +- .../send-list-items-container.component.html | 4 +- .../delete-attachment.component.html | 2 +- .../uri-option.component.html | 6 +-- ...dd-edit-custom-field-dialog.component.html | 2 +- .../custom-fields.component.html | 4 +- .../item-details-section.component.html | 2 +- .../login-details-section.component.html | 10 ++-- .../sshkey-section.component.html | 2 +- .../additional-options.component.html | 2 +- .../autofill-options-view.component.html | 4 +- .../card-details-view.component.html | 4 +- .../custom-fields-v2.component.html | 6 +-- .../login-credentials-view.component.html | 8 +-- .../sshkey-view.component.html | 6 +-- .../view-identity-sections.component.html | 18 +++---- .../add-edit-folder-dialog.component.html | 2 +- .../download-attachment.component.html | 2 +- .../password-history-view.component.html | 2 +- 124 files changed, 414 insertions(+), 285 deletions(-) create mode 100644 libs/components/src/a11y/set-a11y-title-and-aria-label.ts create mode 100644 libs/eslint/components/index.mjs create mode 100644 libs/eslint/components/require-label-on-biticonbutton.mjs diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 187f500828..4b956fd577 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -131,6 +131,7 @@ apps/web/src/translation-constants.ts @bitwarden/team-platform-dev .github/workflows/version-auto-bump.yml @bitwarden/team-platform-dev # ESLint custom rules libs/eslint @bitwarden/team-platform-dev +libs/eslint/components @bitwarden/team-ui-foundation # Typescript tooling tsconfig.base.json @bitwarden/team-platform-dev nx.json @bitwarden/team-platform-dev diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index f8dde376b3..1c27fab697 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5579,5 +5579,9 @@ }, "showLess": { "message": "Show less" + }, + "moreBreadcrumbs": { + "message": "More breadcrumbs", + "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." } } diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html index 8156525301..6a08b4483a 100644 --- a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html @@ -30,7 +30,7 @@ diff --git a/apps/browser/src/platform/popup/layout/popup-header.component.html b/apps/browser/src/platform/popup/layout/popup-header.component.html index 014ebc8641..2aac161b9d 100644 --- a/apps/browser/src/platform/popup/layout/popup-header.component.html +++ b/apps/browser/src/platform/popup/layout/popup-header.component.html @@ -19,8 +19,7 @@ bitIconButton="bwi-angle-left" type="button" *ngIf="showBackButton" - [title]="'back' | i18n" - [attr.aria-label]="'back' | i18n" + [label]="'back' | i18n" [bitAction]="backAction" >

diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index aeeed6f65c..7455921b08 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -67,14 +67,10 @@ class ExtensionPoppedContainerComponent {} - + - + @@ -102,13 +98,7 @@ class MockAddButtonComponent {} @Component({ selector: "mock-popout-button", template: ` - + `, imports: [IconButtonModule], }) @@ -278,7 +268,13 @@ class MockSettingsPageComponent {} - + `, @@ -671,17 +667,13 @@ export const WithVirtualScrollChild: Story = { - + diff --git a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html index 5d313188d8..c6ea52aff6 100644 --- a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html +++ b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html @@ -26,7 +26,7 @@ slot="end" bitIconButton="bwi-trash" [bitAction]="deleteSend" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html index 21b298fb30..8f184c6a0c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html @@ -38,7 +38,7 @@ type="button" buttonType="danger" bitIconButton="bwi-trash" - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html index 567d527745..f4cc27171a 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html @@ -7,7 +7,7 @@ size="small" appCopyField="username" [cipher]="cipher" - [appA11yTitle]="'copyUsername' | i18n" + [label]="'copyUsername' | i18n" > @@ -18,7 +18,7 @@ size="small" appCopyField="password" [cipher]="cipher" - [appA11yTitle]="'copyPassword' | i18n" + [label]="'copyPassword' | i18n" > @@ -28,7 +28,7 @@ size="small" appCopyField="totp" [cipher]="cipher" - [appA11yTitle]="'copyVerificationCode' | i18n" + [label]="'copyVerificationCode' | i18n" > @@ -40,7 +40,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableLogin.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableLogin.key : cipher.name" [appCopyField]="singleCopyableLogin.field" [cipher]="cipher" > @@ -49,7 +49,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasLoginValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasLoginValues" @@ -86,7 +86,7 @@ size="small" appCopyField="cardNumber" [cipher]="cipher" - [appA11yTitle]="'copyNumber' | i18n" + [label]="'copyNumber' | i18n" > @@ -96,7 +96,7 @@ size="small" appCopyField="securityCode" [cipher]="cipher" - [appA11yTitle]="'copySecurityCode' | i18n" + [label]="'copySecurityCode' | i18n" > @@ -107,7 +107,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableCard.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableCard.key : cipher.name" [appCopyField]="singleCopyableCard.field" [cipher]="cipher" showToast @@ -117,7 +117,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasCardValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasCardValues" @@ -142,7 +142,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableIdentity.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableIdentity.key : cipher.name" [appCopyField]="singleCopyableIdentity.field" [cipher]="cipher" showToast @@ -152,7 +152,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasIdentityValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasIdentityValues" @@ -180,9 +180,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" - hasSecureNoteValue ? ('copyNoteTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) - " + [label]="hasSecureNoteValue ? ('copyNoteTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n)" appCopyField="secureNote" [cipher]="cipher" > @@ -193,9 +191,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" - hasSshKeyValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) - " + [label]="hasSshKeyValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n)" [disabled]="!hasSshKeyValues" [bitMenuTriggerFor]="sshKeyOptions" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html index 962f0c914f..42e2779679 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html @@ -3,8 +3,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - [attr.aria-label]="'moreOptionsLabel' | i18n: cipher.name" - [title]="'moreOptionsTitle' | i18n: cipher.name" + [label]="'moreOptionsLabel' | i18n: cipher.name" [disabled]="decryptionFailure" [bitMenuTriggerFor]="moreOptions" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html index 91feaa433a..1ab162b56f 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html @@ -8,7 +8,7 @@ bitIconButton="bwi-sliders" [buttonType]="'muted'" [bitDisclosureTriggerFor]="disclosureRef" - [appA11yTitle]="'filterVault' | i18n" + [label]="'filterVault' | i18n" aria-describedby="filters-applied" >

diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html index 8c76db600a..9b8380a421 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html @@ -33,7 +33,7 @@ type="button" buttonType="danger" bitIconButton="bwi-trash" - [appA11yTitle]="(cipher.isDeleted ? 'deleteForever' : 'delete') | i18n" + [label]="(cipher.isDeleted ? 'deleteForever' : 'delete') | i18n" > diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.html b/apps/browser/src/vault/popup/settings/folders-v2.component.html index 8cea05f9c1..b36b5affc2 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.html +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.html @@ -25,7 +25,7 @@ slot="end" type="button" (click)="openAddEditFolderDialog(folder)" - [appA11yTitle]="'editFolderWithName' | i18n: folder.name" + [label]="'editFolderWithName' | i18n: folder.name" bitIconButton="bwi-pencil-square" class="tw-self-end" data-testid="edit-folder-button" diff --git a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html index 11ed267417..d1e7039084 100644 --- a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html +++ b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html @@ -37,8 +37,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - [attr.aria-label]="'moreOptionsLabel' | i18n: cipher.name" - [title]="'moreOptionsTitle' | i18n: cipher.name" + [label]="'moreOptionsLabel' | i18n: cipher.name" [bitMenuTriggerFor]="moreOptions" > diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 72d40ed750..d99d3686d1 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -4077,5 +4077,9 @@ }, "enableAutotypeDescription": { "message": "Bitwarden does not validate input locations, be sure you are in the right window and field before using the shortcut." + }, + "moreBreadcrumbs": { + "message": "More breadcrumbs", + "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." } } diff --git a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html index 50d34227b5..9c3e607d6e 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html +++ b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html @@ -34,6 +34,7 @@ [bitMenuTriggerFor]="editCollectionMenu" size="small" type="button" + [label]="'editCollection' | i18n" > diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html index 101512dea0..cc90d10fb4 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html @@ -80,7 +80,7 @@ bitIconButton="bwi-trash" bitFormButton [bitAction]="delete" - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" > diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.html b/apps/web/src/app/admin-console/organizations/manage/groups.component.html index 4518513ba7..62d0b5b874 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.html @@ -46,7 +46,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -82,7 +82,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.html b/apps/web/src/app/admin-console/organizations/members/members.component.html index 49946806ef..7e0aa465bf 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.html +++ b/apps/web/src/app/admin-console/organizations/members/members.component.html @@ -106,7 +106,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" *ngIf="showUserManagementControls$ | async" > @@ -350,7 +350,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts index a803f6ef7b..5cb61197b9 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts @@ -51,7 +51,7 @@ const render: Story["render"] = (args) => ({ buttonType="danger" size="default" title="Delete" - aria-label="Delete"> + label="Delete"> `, diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html index e0ffc9a4bc..116af15f57 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html @@ -122,7 +122,7 @@ type="button" bitIconButton="bwi-close" buttonType="muted" - appA11yTitle="{{ 'remove' | i18n }} {{ item.labelName }}" + label="{{ 'remove' | i18n }} {{ item.labelName }}" [disabled]="disabled" (click)="selectionList.deselectItem(item.id); handleBlur()" > diff --git a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html index 4a91fcc2a4..dec257b374 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html @@ -143,7 +143,7 @@ buttonType="danger" class="tw-ml-auto" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" [disabled]="loading" > diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html index 6e87d66d18..1c04c03a8d 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html @@ -62,7 +62,7 @@ buttonType="danger" [bitAction]="delete" *ngIf="editMode" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html index 8a802e4f6a..70165a94fc 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html @@ -89,7 +89,7 @@ @@ -212,7 +212,7 @@ diff --git a/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html b/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html index 1df1e52f7e..dbad422a32 100644 --- a/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html +++ b/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html @@ -39,7 +39,7 @@ type="button" buttonType="danger" (click)="remove(i)" - appA11yTitle="{{ 'remove' | i18n }}" + label="{{ 'remove' | i18n }}" > diff --git a/apps/web/src/app/billing/members/free-bitwarden-families.component.html b/apps/web/src/app/billing/members/free-bitwarden-families.component.html index ddf7c50674..697a5963a7 100644 --- a/apps/web/src/app/billing/members/free-bitwarden-families.component.html +++ b/apps/web/src/app/billing/members/free-bitwarden-families.component.html @@ -53,7 +53,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="appListDropdown" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @if (!isSelfHosted && !sponsoredFamily.validUntil) { diff --git a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html index a09000ef55..465a50ec8c 100644 --- a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html +++ b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html @@ -33,7 +33,7 @@ showToast [valueLabel]="'billingSyncKey' | i18n" [appCopyClick]="clientSecret" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" >

diff --git a/apps/web/src/app/billing/organizations/billing-sync-key.component.html b/apps/web/src/app/billing/organizations/billing-sync-key.component.html index 9736351dec..94a8114034 100644 --- a/apps/web/src/app/billing/organizations/billing-sync-key.component.html +++ b/apps/web/src/app/billing/organizations/billing-sync-key.component.html @@ -33,7 +33,7 @@ bitIconButton="bwi-trash" bitFormButton [bitAction]="deleteConnection" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html index ace3d749a3..f899b8eccb 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html @@ -359,7 +359,7 @@ type="button" [bitIconButton]="totalOpened ? 'bwi-angle-down' : 'bwi-angle-up'" size="small" - aria-hidden="true" + [label]="totalOpened ? ('hidePricingSummary' | i18n) : ('showPricingSummary' | i18n)" >

diff --git a/apps/web/src/app/billing/organizations/change-plan.component.html b/apps/web/src/app/billing/organizations/change-plan.component.html index 75a12122d1..1cd15a7c83 100644 --- a/apps/web/src/app/billing/organizations/change-plan.component.html +++ b/apps/web/src/app/billing/organizations/change-plan.component.html @@ -8,7 +8,7 @@ type="button" size="small" class="tw-float-right" - appA11yTitle="{{ 'cancel' | i18n }}" + label="{{ 'cancel' | i18n }}" (click)="cancel()" >

{{ "changeBillingPlan" | i18n }}

diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html index 1e5690cd85..5167c0a5c3 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html @@ -12,7 +12,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="appListDropdown" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" >

diff --git a/apps/web/src/app/dirt/reports/reports-layout.component.html b/apps/web/src/app/dirt/reports/reports-layout.component.html index 283d9213cc..a27556a7aa 100644 --- a/apps/web/src/app/dirt/reports/reports-layout.component.html +++ b/apps/web/src/app/dirt/reports/reports-layout.component.html @@ -2,7 +2,7 @@
diff --git a/apps/web/src/app/layouts/header/web-header.stories.ts b/apps/web/src/app/layouts/header/web-header.stories.ts index 9715dbf8cd..7abddf01f2 100644 --- a/apps/web/src/app/layouts/header/web-header.stories.ts +++ b/apps/web/src/app/layouts/header/web-header.stories.ts @@ -48,7 +48,7 @@ class MockStateService { @Component({ selector: "product-switcher", - template: ``, + template: ``, standalone: false, }) class MockProductSwitcher {} diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html index f1942a02c2..a44f05a7ed 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html @@ -3,7 +3,7 @@ bitIconButton="bwi bwi-fw bwi-filter" [bitMenuTriggerFor]="content?.menu" [buttonType]="buttonType" - [attr.aria-label]="'switchProducts' | i18n" + [label]="'switchProducts' | i18n" *ngIf="products$ | async" > diff --git a/apps/web/src/app/settings/domain-rules.component.html b/apps/web/src/app/settings/domain-rules.component.html index 8ebeecb429..880e2a6da0 100644 --- a/apps/web/src/app/settings/domain-rules.component.html +++ b/apps/web/src/app/settings/domain-rules.component.html @@ -32,7 +32,7 @@ type="button" buttonType="danger" (click)="remove(i)" - appA11yTitle="{{ 'remove' | i18n }}" + label="{{ 'remove' | i18n }}" >
diff --git a/apps/web/src/app/tools/send/send.component.html b/apps/web/src/app/tools/send/send.component.html index 042046b85f..b79f50311e 100644 --- a/apps/web/src/app/tools/send/send.component.html +++ b/apps/web/src/app/tools/send/send.component.html @@ -156,7 +156,7 @@ type="button" [bitMenuTriggerFor]="sendOptions" bitIconButton="bwi-ellipsis-v" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -101,7 +101,7 @@ bitIconButton="bwi-ellipsis-v" type="button" appStopProp - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html index ad2886b1e5..7cd5129d3f 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html @@ -65,7 +65,7 @@ size="small" bitIconButton="bwi-ellipsis-v" type="button" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" appStopProp > } diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.component.html b/apps/web/src/app/vault/components/vault-items/vault-items.component.html index ef928903a7..5ddccf6a39 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-items.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-items.component.html @@ -56,7 +56,7 @@ bitIconButton="bwi-ellipsis-v" size="small" type="button" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -67,8 +67,7 @@ bitIconButton="bwi-trash" buttonType="danger" size="default" - title="{{ 'delete' | i18n }}" - aria-label="Delete" + label="{{ 'delete' | i18n }}" [bitAction]="deleteDomain" type="submit" bitFormButton diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html index 7ade2e6c63..38cb077c62 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html @@ -29,7 +29,7 @@ bitSuffix bitIconButton="bwi-clone" [bitAction]="copyScimUrl" - [appA11yTitle]="'copyScimUrl' | i18n" + [label]="'copyScimUrl' | i18n" > @@ -46,7 +46,7 @@ bitSuffix [bitIconButton]="showScimKey ? 'bwi-eye-slash' : 'bwi-eye'" [bitAction]="toggleScimKey" - [appA11yTitle]="'toggleVisibility' | i18n" + [label]="'toggleVisibility' | i18n" > {{ "scimApiKeyHelperText" | i18n }} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html index 60993f5570..08e694aa45 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html @@ -58,7 +58,7 @@ bitIconButton="bwi-trash" buttonType="danger" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" [disabled]="loading" > diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html index f203b7a934..07ccd997b9 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html @@ -79,7 +79,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -193,7 +193,7 @@ bitSuffix type="button" [appCopyClick]="signedOutCallbackPath" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -336,7 +336,7 @@ bitSuffix type="button" [appCopyClick]="spEntityId" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -348,7 +348,7 @@ bitSuffix type="button" [appCopyClick]="spEntityIdStatic" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -360,14 +360,14 @@ bitSuffix type="button" [appLaunchClick]="spMetadataUrl" - [appA11yTitle]="'launch' | i18n" + [label]="'launch' | i18n" > @@ -379,7 +379,7 @@ bitSuffix type="button" [appCopyClick]="spAcsUrl" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html index 043ce65b96..2ab82bd837 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html @@ -86,7 +86,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html index ab7c67c7b2..e7f9692beb 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html @@ -7,6 +7,7 @@ (click)="toggle()" [attr.aria-expanded]="open" [attr.aria-controls]="contentId" + [label]="'toggleVisibility' | i18n" >
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html index 24168d0b02..3a2c858ac3 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html @@ -95,7 +95,7 @@ buttonType="danger" bitIconButton="bwi-trash" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html index fbb0dd8888..3399b550ba 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html @@ -40,8 +40,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="tableMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" > @@ -65,8 +64,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tokenMenu" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html index b17e47a39e..11f8e0b9b7 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html @@ -11,12 +11,19 @@ type="button" bitIconButton="bwi-clone" [bitAction]="copyIdentityUrl" + [label]="'copyCustomField' | i18n: identityUrl" > {{ "apiUrl" | i18n }} - +
@@ -27,6 +34,7 @@ type="button" bitIconButton="bwi-clone" [bitAction]="copyOrganizationId" + [label]="'copyCustomField' | i18n: organizationId" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html index bfb7b98542..3d7fc9715c 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html @@ -39,8 +39,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tableMenu" > @@ -72,8 +71,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="serviceAccountMenu" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html index c8a5017578..d01faae4e6 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html @@ -67,8 +67,7 @@ buttonType="main" size="default" [disabled]="disabled" - [attr.title]="'remove' | i18n" - [attr.aria-label]="'remove' | i18n" + [label]="'remove' | i18n" (click)="selectionList.deselectItem(item.id); handleBlur()" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html index bc1655d8b2..236af0d414 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html @@ -43,8 +43,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="tableMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" *ngIf="showMenus" > @@ -77,8 +76,7 @@ bitIconButton="bwi-clone" buttonType="main" size="small" - [title]="'copyUuid' | i18n" - [attr.aria-label]="'copyUuid' | i18n" + [label]="'copyUuid' | i18n" (click)="copyProjectUuidToClipboard(project.id)" > @@ -94,8 +92,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="projectMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" *ngIf="showMenus" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html index 859c7417eb..e5d22a0150 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html @@ -45,8 +45,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tableMenu" > @@ -78,8 +77,7 @@ bitIconButton="bwi-clone" buttonType="main" size="small" - [title]="'copyUuid' | i18n" - [attr.aria-label]="'copyUuid' | i18n" + [label]="'copyUuid' | i18n" (click)="copySecretUuidEvent.emit(secret.id)" > @@ -108,8 +106,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="secretMenu" > diff --git a/eslint.config.mjs b/eslint.config.mjs index c4018b7625..c745f073fc 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -12,6 +12,7 @@ import angularRxjs from "eslint-plugin-rxjs-angular"; import storybook from "eslint-plugin-storybook"; import platformPlugins from "./libs/eslint/platform/index.mjs"; +import componentPlugins from "./libs/eslint/components/index.mjs"; export default tseslint.config( ...storybook.configs["flat/recommended"], @@ -174,6 +175,7 @@ export default tseslint.config( plugins: { "@angular-eslint/template": angular.templatePlugin, tailwindcss: eslintPluginTailwindCSS, + "@bitwarden/components": componentPlugins, }, rules: { "@angular-eslint/template/button-has-type": "error", @@ -188,6 +190,10 @@ export default tseslint.config( "tailwindcss/enforces-negative-arbitrary-values": "error", "tailwindcss/enforces-shorthand": "error", "tailwindcss/no-contradicting-classname": "error", + "@bitwarden/components/require-label-on-biticonbutton": [ + "error", + { ignoreIfHas: ["bitPasswordInputToggle"] }, + ], }, }, diff --git a/libs/angular/src/vault/components/spotlight/spotlight.component.html b/libs/angular/src/vault/components/spotlight/spotlight.component.html index e445640cff..0d0e95e191 100644 --- a/libs/angular/src/vault/components/spotlight/spotlight.component.html +++ b/libs/angular/src/vault/components/spotlight/spotlight.component.html @@ -18,9 +18,8 @@ size="small" *ngIf="!persistent" (click)="handleDismiss()" - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" class="-tw-me-2" + [label]="'close' | i18n" > diff --git a/libs/auth/src/angular/input-password/input-password.component.html b/libs/auth/src/angular/input-password/input-password.component.html index d39215b2d6..d56fe6a27f 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -45,7 +45,7 @@ type="button" bitIconButton="bwi-generate" bitSuffix - [appA11yTitle]="'generatePassword' | i18n" + [label]="'generatePassword' | i18n" (click)="generatePassword()" > - + ``` ## `[bitSubmit]` Disabled Form Submit diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index dd901cd247..88383fe85a 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -7,6 +7,7 @@ import { delay, of } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { A11yTitleDirective } from "../a11y"; import { ButtonModule } from "../button"; import { FormFieldModule } from "../form-field"; import { IconButtonModule } from "../icon-button"; @@ -28,20 +29,21 @@ const template = ` Email - + - + `; @Component({ selector: "app-promise-example", template, imports: [ + A11yTitleDirective, AsyncActionsModule, ButtonModule, FormFieldModule, @@ -86,6 +88,7 @@ class PromiseExampleComponent { selector: "app-observable-example", template, imports: [ + A11yTitleDirective, AsyncActionsModule, ButtonModule, FormFieldModule, diff --git a/libs/components/src/async-actions/standalone.mdx b/libs/components/src/async-actions/standalone.mdx index f484ea01c5..a781f40d85 100644 --- a/libs/components/src/async-actions/standalone.mdx +++ b/libs/components/src/async-actions/standalone.mdx @@ -63,7 +63,7 @@ from how click handlers are usually defined with the output syntax `(click)="han ```html -`; +`; ``` ## Stories diff --git a/libs/components/src/async-actions/standalone.stories.ts b/libs/components/src/async-actions/standalone.stories.ts index 1ed6f6c5a5..99cde70566 100644 --- a/libs/components/src/async-actions/standalone.stories.ts +++ b/libs/components/src/async-actions/standalone.stories.ts @@ -16,7 +16,7 @@ const template = /*html*/ ` - `; + `; @Component({ template, diff --git a/libs/components/src/banner/banner.component.html b/libs/components/src/banner/banner.component.html index 581a56d86c..bfde8135da 100644 --- a/libs/components/src/banner/banner.component.html +++ b/libs/components/src/banner/banner.component.html @@ -19,8 +19,7 @@ buttonType="main" size="small" (click)="onClose.emit()" - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" + [label]="'close' | i18n" > } diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.html b/libs/components/src/breadcrumbs/breadcrumbs.component.html index d062e82548..b63b21de76 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.html +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.html @@ -35,6 +35,7 @@ bitIconButton="bwi-ellipsis-h" [bitMenuTriggerFor]="overflowMenu" size="small" + [label]="'moreBreadcrumbs' | i18n" > @for (breadcrumb of overflow; track breadcrumb) { diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.ts b/libs/components/src/breadcrumbs/breadcrumbs.component.ts index a1a6e73245..3c24f91be9 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.ts @@ -2,6 +2,8 @@ import { CommonModule } from "@angular/common"; import { Component, ContentChildren, QueryList, input } from "@angular/core"; import { RouterModule } from "@angular/router"; +import { I18nPipe } from "@bitwarden/ui-common"; + import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; import { MenuModule } from "../menu"; @@ -16,7 +18,7 @@ import { BreadcrumbComponent } from "./breadcrumb.component"; @Component({ selector: "bit-breadcrumbs", templateUrl: "./breadcrumbs.component.html", - imports: [CommonModule, LinkModule, RouterModule, IconButtonModule, MenuModule], + imports: [I18nPipe, CommonModule, LinkModule, RouterModule, IconButtonModule, MenuModule], }) export class BreadcrumbsComponent { readonly show = input(3); diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts index 98af3c0ae7..893f645a91 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts @@ -2,9 +2,12 @@ import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; + import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; import { MenuModule } from "../menu"; +import { I18nMockService } from "../utils"; import { BreadcrumbComponent } from "./breadcrumb.component"; import { BreadcrumbsComponent } from "./breadcrumbs.component"; @@ -26,6 +29,16 @@ export default { decorators: [ moduleMetadata({ imports: [LinkModule, MenuModule, IconButtonModule, RouterModule, BreadcrumbComponent], + providers: [ + { + provide: I18nService, + useFactory: () => { + return new I18nMockService({ + moreBreadcrumbs: "More breadcrumbs", + }); + }, + }, + ], }), applicationConfig({ providers: [ diff --git a/libs/components/src/dialog/dialog/dialog.component.html b/libs/components/src/dialog/dialog/dialog.component.html index 94fc9ef06a..9f140ca762 100644 --- a/libs/components/src/dialog/dialog/dialog.component.html +++ b/libs/components/src/dialog/dialog/dialog.component.html @@ -37,8 +37,7 @@ buttonType="main" size="default" bitDialogClose - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" + [label]="'close' | i18n" > } diff --git a/libs/components/src/dialog/dialog/dialog.stories.ts b/libs/components/src/dialog/dialog/dialog.stories.ts index 71e07542ed..f93ef1a2f2 100644 --- a/libs/components/src/dialog/dialog/dialog.stories.ts +++ b/libs/components/src/dialog/dialog/dialog.stories.ts @@ -101,8 +101,7 @@ export const Default: Story = { bitIconButton="bwi-trash" buttonType="danger" size="default" - title="Delete" - aria-label="Delete"> + label="Delete">
`, @@ -219,7 +218,7 @@ export const WithCards: Story = {

Foo

- + @@ -239,7 +238,7 @@ export const WithCards: Story = {

Bar

- + @@ -265,8 +264,7 @@ export const WithCards: Story = { bitIconButton="bwi-trash" buttonType="danger" size="default" - title="Delete" - aria-label="Delete"> + label="Delete"> diff --git a/libs/components/src/disclosure/disclosure.component.ts b/libs/components/src/disclosure/disclosure.component.ts index 703c815087..2d73d7d8ad 100644 --- a/libs/components/src/disclosure/disclosure.component.ts +++ b/libs/components/src/disclosure/disclosure.component.ts @@ -28,6 +28,7 @@ let nextId = 0; * bitIconButton="bwi-sliders" * [buttonType]="'muted'" * [bitDisclosureTriggerFor]="disclosureRef" + * [label]="'Settings' | i18n" * > * click button to hide this content * ``` diff --git a/libs/components/src/disclosure/disclosure.stories.ts b/libs/components/src/disclosure/disclosure.stories.ts index bb3680c1f3..2e45964cca 100644 --- a/libs/components/src/disclosure/disclosure.stories.ts +++ b/libs/components/src/disclosure/disclosure.stories.ts @@ -27,7 +27,7 @@ export const DisclosureWithIconButton: Story = { render: (args) => ({ props: args, template: /*html*/ ` - click button to hide this content `, diff --git a/libs/components/src/drawer/drawer-header.component.html b/libs/components/src/drawer/drawer-header.component.html index 863b19edfb..2723744eda 100644 --- a/libs/components/src/drawer/drawer-header.component.html +++ b/libs/components/src/drawer/drawer-header.component.html @@ -5,11 +5,5 @@ {{ title() }} - + diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts index e070765ec8..7aeb2f6304 100644 --- a/libs/components/src/form-field/form-field.stories.ts +++ b/libs/components/src/form-field/form-field.stories.ts @@ -239,8 +239,8 @@ export const Readonly: Story = { Input - - + + @@ -261,7 +261,7 @@ export const Readonly: Story = { Input - + @@ -309,11 +309,11 @@ export const ButtonInputGroup: Story = {
- + - - - + + + `, }), @@ -326,11 +326,11 @@ export const DisabledButtonInputGroup: Story = { template: /*html*/ ` Label - + - - - + + + `, @@ -345,9 +345,9 @@ export const PartiallyDisabledButtonInputGroup: Story = { Label - - - + + + `, }), diff --git a/libs/components/src/form-field/password-input-toggle.spec.ts b/libs/components/src/form-field/password-input-toggle.spec.ts index 95110f2bd9..72f2481d78 100644 --- a/libs/components/src/form-field/password-input-toggle.spec.ts +++ b/libs/components/src/form-field/password-input-toggle.spec.ts @@ -20,7 +20,13 @@ import { BitPasswordInputToggleDirective } from "./password-input-toggle.directi Password - + `, diff --git a/libs/components/src/form-field/password-input-toggle.stories.ts b/libs/components/src/form-field/password-input-toggle.stories.ts index d46ec92ab3..3d50a4eb75 100644 --- a/libs/components/src/form-field/password-input-toggle.stories.ts +++ b/libs/components/src/form-field/password-input-toggle.stories.ts @@ -48,7 +48,7 @@ export const Default: Story = { Password - + `, @@ -63,7 +63,7 @@ export const Binding: Story = { Password - +